2013-11-21 50 views
0

如果我編譯過程我不明白的錯誤,但我看到這些文字(我怎麼能用這樣的建議):包含DML語句for循環遊標將重構使用

的遊標循環,包含DML語句需要重構使用大量聚集和FORALL

如果我編譯這個我得到總是得分:

start:2013-11-21 08:16:54 
end:2013-11-21 08:16:54 

我的代碼:

CREATE OR REPLACE PROCEDURE PROC_AAA 
IS 
    PRAGMA AUTONOMOUS_TRANSACTION; 
    company_    VARCHAR2 (2) := 'IT'; 
    ok_     BOOLEAN; 
    updated_    BOOLEAN; 
    error_msg_   VARCHAR2 (4000); 
    category_    VARCHAR2 (50); 
    exist_atrribute_id_ VARCHAR2 (50); 
    exist_value_   NUMBER; 
    objid_    ROWID; 
    var_rows    NUMBER (5); 

    CURSOR cur_dane_wej 
    IS 
     SELECT * 
     FROM dane_wejsciowe_cns 
     WHERE status = 'NEW' 
     FOR UPDATE; 
BEGIN 
    DBMS_OUTPUT.put_line (
     'start:' || TO_CHAR (SYSDATE, 'YYYY-MM-DD hh24:mi:ss')); 

    FOR cur_dane_wej_read IN cur_dane_wej 
    LOOP 
     BEGIN 
     SAVEPOINT cur_dane_wej_svp; 
     updated_ := FALSE; 
     error_msg_ := NULL; 

     category_ := TERMINAL_API.Get_Category_Id (cur_dane_wej_read.IMEI_NO); 

     exist_atrribute_id_ := 
      IFSAPP.SER_NUM_ATTRIBUTE_API.CHECK_EXIST (
       COMPANY_, 
       category_, 
       cur_dane_wej_read.IMEI_NO, 
       cur_dane_wej_read.KOD_CECHY); 

     SELECT COUNT (*) 
      INTO exist_value_ 
      FROM IFSAPP.SER_NUM_ATTRIBUTE 
      WHERE  SERIAL_NO = cur_dane_wej_read.IMEI_NO 
       AND COMPANY = company_ 
       AND CATEGORY_ID = category_ 
       AND ATTRIBUTE_ID = cur_dane_wej_read.WARTOSC_CECHY 
       AND NVL (VALUE, '_dummy_') = 
         NVL (cur_dane_wej_read.KOD_CECHY, '_dummy_'); 



     DBMS_OUTPUT.put_line (
       cur_dane_wej_read.KOD_CECHY 
      || ' ' 
      || cur_dane_wej_read.WARTOSC_CECHY); 
     DBMS_OUTPUT.put_line (
       'kategoria: ' 
      || category_ 
      || ' imei: ' 
      || cur_dane_wej_read.IMEI_NO); 


     IF exist_atrribute_id_ = 'TRUE' 
     THEN 
      SELECT objid 
       INTO objid_ 
       FROM SER_NUM_ATTRIBUTE 
      WHERE  COMPANY = company_ 
        AND CATEGORY_ID = category_ 
        AND SERIAL_NO = cur_dane_wej_read.IMEI_NO 
        AND ATTRIBUTE_ID = cur_dane_wej_read.KOD_CECHY; 

      DBMS_OUTPUT.put_line ('objid: ' || objid_); 

      IF exist_value_ > 0 
      THEN 
       DBMS_OUTPUT.put_line ('--> wartosc cechy istnieje '); 
       NULL; 
      ELSE 
       DBMS_OUTPUT.put_line ('zmodyfikowano wartosc cechy'); 
       updated_ := TRUE; 
      END IF; 
     ELSE 
      DBMS_OUTPUT.put_line (
       'kod cechy nie istnieje.. trwa dodanie nowego kodu cechy'); 
      --      IFSAPP.SER_NUM_ATTRIBUTE_API.SET_VALUE (company_, category_id_,cur_dane_wej_read.IMEI_NO, cur_dane_wej_read.KOD_CECHY, cur_dane_wej_read.WARTOSC_CECHY, 'DODANO NOWY KOD CECHY'); 
      updated_ := TRUE; 
     END IF; 

     IF updated_ = TRUE 
     THEN 
      DBMS_OUTPUT.put_line ('aktualizacja danych w tabeli wejsciowej'); 

      UPDATE dane_wejsciowe_cns 
       SET status = 'DONE', 
        MESSAGE = ' ', 
        DATA_PRZETWORZENIA = SYSDATE 
      WHERE CURRENT OF cur_dane_wej; 
     ELSE 
      UPDATE dane_wejsciowe_cns 
       SET status = 'SKIPPED', 
        MESSAGE = ' ', 
        DATA_PRZETWORZENIA = SYSDATE 
      WHERE CURRENT OF cur_dane_wej; 
     END IF; 

     COMMIT; 
     EXCEPTION 
     WHEN OTHERS 
     THEN 
      ROLLBACK TO cur_dane_wej_svp; 
      error_msg_ := 'Błąd: - ' || SQLCODE || ' -ERROR- ' || SQLERRM; 

      UPDATE dane_wejsciowe_cns 
       SET status = 'ERROR', 
        MESSAGE = error_msg_, 
        DATA_PRZETWORZENIA = SYSDATE 
      WHERE CURRENT OF cur_dane_wej; 

      COMMIT; 
     END; 
    END LOOP; 

    COMMIT; 
    DBMS_OUTPUT.put_line (
     'end:' || TO_CHAR (SYSDATE, 'YYYY-MM-DD hh24:mi:ss')); 
END PROC_AAA; 

回答

0

學會使用批量收藏,看看這個article

+0

好的,但我必須使用這個批量收集?也許我可以使用執行立即? – Przemek

+0

批量收集並立即執行是兩件完全不同的事情。使用批量收集,您可以一次獲取更多行到一個集合(數組)中。立即執行用於執行動態SQL,而不是靜態SQL。 –