2011-11-17 17 views
5

Występuje błąd poniżej podczas tworzenia tej procedury.Nie można skompilować PL/SQL z BULK COLLECT i FORALL

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; 

Procedura

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

Pojedyncza instrukcja SQL byłaby prostsza i szybsza. –

+0

Masz kilka pytań, na które udzielono odpowiedzi i oczywiście ci pomógł, ale ich nie zaakceptowałeś (http://u.sbhat.me/t6SXUH). Proszę, niech inni nie będą skłonni ci pomóc. – Sathya

Odpowiedz

6

Nie można * indywidualne referencyjne pól podczas korzystania FORALL - dlatego masz błąd PLS-00436.

Aby obejść ten problem, będziesz musiał użyć tablic asocjacyjnych, aby odnieść się do poszczególnych pól .

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; 

* uwaga to ograniczenie nie jest już obecna w Oracle 11g +


Ponadto, jak @jonearlescomments, można po prostu użyć pojedynczego 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);