log errors
Oracle 10gR2から、次の句を使用できます。
EXECUTE DBMS_ERRLOG.CREATE_ERROR_LOG('NORMAL_TABLE');
INSERT INTO normal_table
SELECT ... FROM temp_table
LOG ERRORS REJECT LIMIT UNLIMITED;
最も単純な形で。次に、発生したエラーを確認できます。
SELECT ora_err_mesg$
FROM err$_normal_table;
ここCREATE_ERROR_LOG
での手順の詳細。
このアプローチは9iから機能すると思いますが、テストに使用できるインスタンスがないため、これは実際には11gR2
アップデートで実行されます。9iでテストおよび調整(PLS-00436を回避するため):
declare
type t_temp_table is table of temp_table%rowtype;
l_temp_table t_temp_table;
l_err_code err_table.err_code%type;
l_err_msg err_table.err_msg%type;
l_id err_table.id%type;
cursor c is select * from temp_table;
error_array exception;
pragma exception_init(error_array, -24381);
begin
open c;
loop
fetch c bulk collect into l_temp_table limit 100;
exit when l_temp_table.count = 0;
begin
forall i in 1..l_temp_table.count save exceptions
insert into normal_table
values l_temp_table(i);
exception
when error_array then
for j in 1..sql%bulk_exceptions.count loop
l_id := l_temp_table(sql%bulk_exceptions(j).error_index).id;
l_err_code := sql%bulk_exceptions(j).error_code;
l_err_msg := sqlerrm(-1 * sql%bulk_exceptions(j).error_code);
insert into err_table(id, err_code, err_msg)
values (l_id, l_err_code, l_err_msg);
end loop;
end;
end loop;
end;
/
id
デモの目的で行った、単なるではなく、すべての実際の列を使用します。
create table normal_table(id number primary key);
create table temp_table(id number);
create table err_table(id number, err_code number, err_msg varchar2(2000));
insert into temp_table values(42);
insert into temp_table values(42);
次に、上記の匿名ブロックを実行します...
select * from normal_table;
ID
----------
42
column err_msg format a50
select * from err_table;
ID ERR_CODE ERR_MSG
---------- ---------- --------------------------------------------------
42 1 ORA-00001: unique constraint (.) violated
これは、いくつかのレベルでは満足のいくものではありません-コーディングが多く、例外がたくさんある場合は遅くなり(それらの個々の挿入のため)、違反した制約(または他のエラーの詳細)が表示されず、表示されませんロールバックしてもエラーを保持します。ただし、それが問題である場合は、自律型トランザクションを呼び出してログに記録することもできますが、ここでは疑問です。
句について心配したくないほど少量のデータがある場合はlimit
、少し単純化できます。
declare
type t_temp_table is table of temp_table%rowtype;
l_temp_table t_temp_table;
l_err_code err_table.err_code%type;
l_err_msg err_table.err_msg%type;
l_id err_table.id%type;
error_array exception;
pragma exception_init(error_array, -24381);
begin
select * bulk collect into l_temp_table from temp_table;
forall i in 1..l_temp_table.count save exceptions
insert into normal_table
values l_temp_table(i);
exception
when error_array then
for j in 1..sql%bulk_exceptions.count loop
l_id := l_temp_table(sql%bulk_exceptions(j).error_index).id;
l_err_code := sql%bulk_exceptions(j).error_code;
l_err_msg := sqlerrm(-1 * sql%bulk_exceptions(j).error_code);
insert into err_table(id, err_code, err_msg)
values (l_id, l_err_code, l_err_msg);
end loop;
end;
/
9iのドキュメントはもうオンラインではないようですが、これは新機能のドキュメントであり、多くの人がそれについて書いています-以前にもここで質問されました。