2017-07-25 11 views
0
CREATE TABLE T1 (EMP_NAME VARCHAR2 (40)); 

    INSERT INTO t1 
     VALUES ('Vinoth'); 

    COMMIT; 

    CREATE TABLE T2 (EMP_NAME VARCHAR2 (40)); 

    CREATE OR REPLACE PACKAGE TEST_PKG_V 
    AS 
     PROCEDURE P_MAIN (p_status OUT VARCHAR2); 

     TYPE T1_TYPE IS RECORD (EMP_NAME T1.EMP_NAME%TYPE); 

     TYPE T1_TBL IS TABLE OF T1_TYPE; 
    END TEST_PKG_V; 
    /

    CREATE OR REPLACE PACKAGE BODY TEST_PKG_V 
    AS 
     PROCEDURE P_MAIN (p_status OUT VARCHAR2) 
     IS 
      LV_T1_TBL T1_TBL := T1_TBL(); 

      CURSOR T1_CUR 
      IS 
      (SELECT EMP_NAME FROM t1); 

     BEGIN 
      OPEN T1_CUR; 

      LOOP 
      FETCH T1_CUR 
       BULK COLLECT INTO LV_T1_TBL 
       LIMIT 10000; 

      INSERT INTO t2 (EMP_NAME) 
       SELECT EMP_NAME FROM TABLE (LV_T1_TBL); 

      EXIT WHEN T1_CUR%NOTFOUND; 
      END LOOP; 

      COMMIT; 
     EXCEPTION 
      WHEN OTHERS 
      THEN 
      p_status := 'FAIL'; 
      RAISE; 
     END P_MAIN; 
    END TEST_PKG_V; 
/
DECLARE 
VAR VARCHAR2(4000); 
BEGIN 
TEST_PKG_V.P_MAIN(VAR); 
END; 

プロシージャを実行すると、ORA-00902:無効なデータ型がスローされます。 プロシージャ内のinsert文をコメントアウトすると、完全に正常に動作しています。何が問題なのか、解決に手伝ってください。ORA-00902:無効なデータ型

+1

使用: '1 .. LV_T1_TBL.COUNT LOOP INSERT INSERT INTO T2にFORALLのINDX(EMP_NAME)VALUES(LV_T1_TBL(INDX)); END LOOP; 'あなたのinsertステートメントの場所。 FORALL文の詳細は、[here](http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html)を参照してください。 – krokodilko

答えて

0

このようにするには、パッケージの外にタイプを作成する必要があります。ここに修正版があります。欠点は、型が作成されていることです。列の型を変更するためにテーブルを変更すると、型を変更するのを忘れるかもしれません。あなたが直接に反復することによってそれを行うことができ、あるいは

CREATE OR REPLACE PACKAGE TEST_PKG_V AS 

    TYPE T1_TYPE IS RECORD (EMP_NAME T1.EMP_NAME%TYPE); 
    TYPE T1_TBL IS TABLE OF T1_TYPE; 

    PROCEDURE P_MAIN (p_status OUT VARCHAR2); 
    FUNCTION GET_T1 RETURN T1_TBL PIPELINED; 

END TEST_PKG_V; 
/

CREATE OR REPLACE PACKAGE BODY TEST_PKG_V IS 

CURSOR T1_CUR IS (SELECT EMP_NAME FROM t1); 

FUNCTION GET_T1 RETURN T1_TBL PIPELINED IS 
    LV_T1_TBL T1_TBL; 
BEGIN 
    OPEN T1_CUR; 
    FETCH T1_CUR BULK COLLECT INTO LV_T1_TBL; 
    CLOSE T1_CUR; 
    FOR IDX IN 1..LV_T1_TBL.COUNT LOOP 
    PIPE ROW (LV_T1_TBL(IDX)); 
    END LOOP; 
END; 

PROCEDURE P_MAIN (p_status OUT VARCHAR2) IS 
BEGIN 
    INSERT INTO t2 (EMP_NAME) SELECT EMP_NAME FROM TABLE (GET_T1); 
    COMMIT; 
EXCEPTION 
    WHEN OTHERS THEN 
    p_status := 'FAIL'; 
    RAISE; 
END P_MAIN; 
END TEST_PKG_V; 
/

:あなたはあなたのタイプは汎用的なものとあなたのテーブルに適応する場合

CREATE TYPE T1_TYPE AS OBJECT (EMP_NAME VARCHAR2(40)); 
CREATE TYPE T1_TBL AS TABLE OF T1_TYPE; 

CREATE OR REPLACE PACKAGE TEST_PKG_V 
AS 
    PROCEDURE P_MAIN (p_status OUT VARCHAR2); 
END TEST_PKG_V; 
/

CREATE OR REPLACE PACKAGE BODY TEST_PKG_V 
AS 
    PROCEDURE P_MAIN (p_status OUT VARCHAR2) 
    IS 
     LV_T1_TBL T1_TBL; 

     CURSOR T1_CUR 
     IS 
     (SELECT T1_TYPE(EMP_NAME) EMP_NAME FROM t1); 

    BEGIN 
     OPEN T1_CUR; 

     LOOP 
     FETCH T1_CUR 
      BULK COLLECT INTO LV_T1_TBL 
      LIMIT 10000; 

     INSERT INTO t2 (EMP_NAME) 
      SELECT EMP_NAME FROM TABLE (LV_T1_TBL); 

     EXIT WHEN T1_CUR%NOTFOUND; 
     END LOOP; 

     COMMIT; 
    EXCEPTION 
     WHEN OTHERS 
     THEN 
     p_status := 'FAIL'; 
     RAISE; 
    END P_MAIN; 
END TEST_PKG_V; 
/

は、私はあなたがそれをそのような何かをしなければならないだろうと思いますカーソル:

CREATE OR REPLACE PACKAGE TEST_PKG_V AS 

    TYPE T1_TYPE IS RECORD (EMP_NAME T1.EMP_NAME%TYPE); 
    TYPE T1_TBL IS TABLE OF T1_TYPE; 
    PROCEDURE P_MAIN (p_status OUT VARCHAR2); 

END TEST_PKG_V; 
/

CREATE OR REPLACE PACKAGE BODY TEST_PKG_V IS 

PROCEDURE P_MAIN (p_status OUT VARCHAR2) IS 
    CURSOR T1_CUR IS (SELECT EMP_NAME FROM t1); 
BEGIN 
    FOR CURRENT_ROW IN T1_CUR LOOP 
    INSERT INTO t2 (EMP_NAME) VALUES (CURRENT_ROW.EMP_NAME); 
    END LOOP; 
    COMMIT; 
EXCEPTION 
    WHEN OTHERS THEN 
    p_status := 'FAIL'; 
    RAISE; 
END P_MAIN; 

END TEST_PKG_V; 
/
関連する問題