2011-11-17 29 views
5

创建此过程时出现以下错误。无法使用BULK COLLECT和FORALL编译PL/SQL

CREATE OR replace PROCEDURE Remove_sv_duplicate 
IS 
    TYPE sv_bulk_collect 
    IS TABLE OF tt%ROWTYPE; 
    sv_rec SV_BULK_COLLECT; 
    CURSOR cur_data IS 
    SELECT * 
    FROM tt 
    WHERE ROWID IN (SELECT ROWID 
        FROM (SELECT ROWID, 
            Row_number() over (PARTITION BY portingtn, 
            nnsp 
            , onsp, 
            spid, 
            Trunc(
              createddate, 
            'MI') ORDER BY portingtn) dup 
          FROM tt) 
        WHERE dup > 1); 
BEGIN 
    OPEN cur_data; 

    LOOP 
     FETCH cur_data BULK COLLECT INTO sv_rec LIMIT 1000; 

     FORALL i IN 1..sv_rec.COUNT 
     INSERT INTO soa_temp_sv_refkey_fordelete 
        (referencekey, 
        spid, 
        nnsp, 
        onsp, 
        portingtn) 
     (SELECT referencekey, 
       spid, 
       nnsp, 
       onsp, 
       portingtn 
     FROM tt 
     WHERE portingtn = Sv_rec(i).portingtn 
       AND spid = Sv_rec(i).spid 
       AND nnsp = Sv_rec(i).nnsp 
       AND onsp = Sv_rec(i).onsp 
       AND svid IS NULL); 

     EXIT WHEN cur_data%notfound; 
    END LOOP; 

    CLOSE cur_data; 

    COMMIT; 
END; 

程序

Error(23,5): PL/SQL: SQL Statement ignored 
Error(25,27): PLS-00382: expression is of wrong type 
Error(25,27): PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records 
Error(26,27): PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records 
Error(26,27): PLS-00382: expression is of wrong type 
Error(27,27): PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records   
Error(27,27): PLS-00382: expression is of wrong type 
Error(28,27): PL/SQL: ORA-22806: not an object or REF  
Error(28,27): PLS-00382: expression is of wrong type 
Error(28,27): PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records 
+1

单个SQL语句会更简单快捷。 –

+0

你有一堆已经回答的问题,显然对你有帮助,但你没有[接受他们](http://u.sbhat.me/t6SXUH)。其他人也许不会倾向于帮助你。 – Sathya

回答

6

你不能*当你使用FORALL参考各个领域 - 这就是为什么你得到的PLS-00436错误。

为了解决这个问题,您必须利用关联数组来引用个别的 字段。

DECLARE 

    TYPE tt_rectype IS RECORD (
     referencekey tt.referencekey%TYPE, 
     spid tt.spid%TYPE, 
     nnsp tt.hiredate%TYPE, 
     onsp tt.deptno%TYPE, 
     portingtn tt.portingtn%TYPE); 

    TYPE tt_aa_type 
     IS TABLE OF TT_RECTYPE INDEX BY PLS_INTEGER; 

    tt_aa TT_AA_TYPE; 
    CURSOR cur_data IS 
     SELECT * 
     FROM tt 
     WHERE ROWID IN (SELECT ROWID 
         FROM (SELECT ROWID, 
             Row_number() over (PARTITION BY portingtn 
             , 
             nnsp 
             , onsp, 
             spid, 
             Trunc(
               createddate 
             , 'MI') ORDER BY portingtn) dup 
           FROM tt) 
         WHERE dup > 1); 
BEGIN 
    OPEN cur_data; 

    LOOP 
     FETCH cur_data BULK COLLECT INTO tt_aa LIMIT 1000; 

     FORALL i IN 1..tt_aa.COUNT 
      INSERT INTO soa_temp_sv_refkey_fordelete 
         (referencekey, 
         spid, 
         nnsp, 
         onsp, 
         portingtn) 
      (SELECT referencekey, 
        spid, 
        nnsp, 
        onsp, 
        portingtn 
      FROM tt 
      WHERE portingtn = Tt_aa(i).portingtn 
        AND spid = Tt_aa(i).spid 
        AND nnsp = Tt_aa(i).nnsp 
        AND onsp = Tt_aa(i).onsp 
        AND svid IS NULL); 

     EXIT WHEN cur_data%notfound; 
    END LOOP; 

    CLOSE cur_data; 

    COMMIT; 
END; 

* 注意到这一限制不再存在在Oracle 11g中+


此外,@jonearlescomments,你可以只使用一个SQL语句....

INSERT INTO soa_temp_sv_refkey_fordelete 
      (referencekey, 
      spid, 
      nnsp, 
      onsp, 
      portingtn) 
SELECT referencekey, 
     spid, 
     nnsp, 
     onsp, 
     portingtn 
FROM tt 
WHERE ROWID IN (SELECT ROWID 
       FROM (SELECT ROWID, 
           Row_number() over (PARTITION BY portingtn, nnsp 
           , onsp, 
           spid, 
           Trunc(
             createddate 
           , 'MI') ORDER BY portingtn) dup 
         FROM tt) 
       WHERE dup > 1);