2016-04-05 8 views
0

いくつかの行を挿入する際にエラーが発生するのを避けるためにこの例外を置いていますが、なぜ実行できるのかわかりません。forall plsqlにエラーをキャッチする方法

DECLARE 
TYPE dataDate IS TABLE OF DATE; 
l_dataDate dataDate; 
BEGIN 
select data1 BULK COLLECT INTO l_dataDate from USER.TABLE_DATA; 
FORALL i IN l_dataDate.FIRST..l_dataDate.LAST 
    BEGIN   
     INSERT INTO USER.DIMDATE SELECT 
     to_number(to_char(l_dataDate(i), 'YYYYMMDDHH24MISS')), 
     to_number(to_char(l_dataDate(i), 'YYYYMMDD')), 
     l_dataDate(i), 
     to_number(to_char(l_dataDate(i), 'DD')), 
     to_char (l_dataDate(i), 'Day'), 
     to_number(to_char (l_dataDate(i), 'MM')), 
     to_char (l_dataDate(i), 'Month'), 
     to_number(to_char(l_dataDate(i), 'YYYY')) FROM DUAL 
     WHERE NOT EXISTS (SELECT 1 FROM USER.DIMDATE WHERE COD_FECHA=to_number(to_char(l_dataDate(i), 'YYYYMMDDHH24MISS'))); 
     COMMIT; 
    EXCEPTION 
    WHEN OTHERS THEN 
     dbms_output.put_line('ERROR '||SUBSTR(SQLERRM, 1, 200)); 
    END; 
END; 
/

このようなことは可能でしょうか?前もって感謝します。

+2

「一括収集...保存例外」を実行するとします。 https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1422998100346727312 –

答えて

2

bulk collectsave exceptionsを入れたいと思います。

DECLARE 
    TYPE dataDate IS TABLE OF DATE; 
    l_dataDate dataDate; 

    dml_errors EXCEPTION; 
    PRAGMA exception_init(dml_errors, -24381); 
BEGIN 
    select data1 
    BULK COLLECT INTO l_dataDate 
    from USER.TABLE_DATA; 

BEGIN 
    FORALL i IN l_dataDate.FIRST..l_dataDate.LAST SAVE EXCEPTIONS 
    INSERT INTO USER.DIMDATE 
     SELECT 
      to_number(to_char(l_dataDate(i), 'YYYYMMDDHH24MISS')), 
      to_number(to_char(l_dataDate(i), 'YYYYMMDD')), 
      l_dataDate(i), 
      to_number(to_char(l_dataDate(i), 'DD')), 
      to_char (l_dataDate(i), 'Day'), 
      to_number(to_char (l_dataDate(i), 'MM')), 
      to_char (l_dataDate(i), 'Month'), 
      to_number(to_char(l_dataDate(i), 'YYYY')) 
    FROM DUAL 
    WHERE NOT EXISTS (SELECT 1 
         FROM USER.DIMDATE 
         WHERE COD_FECHA=to_number(
             to_char(l_dataDate(i), 
               'YYYYMMDDHH24MISS'))); 
EXCEPTION 
    WHEN dml_errors 
    THEN 
    FOR i IN 1..sql%bulk_exceptions.count 
    LOOP 
     <<do something with the exceptions>> 
    END LOOP; 
END; 

このような場合は、PL/SQLをまったく使用する必要はありません。 table_dataに無効なデータが記録される必要がある場合は、DMLエラー・ロギングを使用して単一のINSERT文を書いてください。

+0

ありがとうございます。たとえば、2番目の挿入箇所にエラーが表示された場合はどうなりますか?例外はforal文にないため、他の行は挿入されません。 – lgerras84

+2

@ Igerras84 - 実際にテストしましたか? 'save exceptions'は例外を保存します。コレクションの2番目の要素がエラーを生成すると、 'forall'は引き続きオンになります。それは外部例外ハンドラで報告され、 'sql%bulk_exceptions'コレクションを繰り返してエラーに関する情報を取得できます。これは、ループの繰り返し内で例外を処理しなければならない 'for'ループがあった場合とは異なります。 –

関連する問題