Oracle 保存异常未捕获ORA-01438的完整错误描述
save exceptions没有捕获ORA-01438:值大于此列允许的指定精度的完整错误描述,它只抛出一般错误,没有捕获列名和大小。任何变通方法都可以与此代码集成,以获得与错误相关联的完整列描述Oracle 保存异常未捕获ORA-01438的完整错误描述,oracle,plsql,oracle11g,bulk-collect,Oracle,Plsql,Oracle11g,Bulk Collect,save exceptions没有捕获ORA-01438:值大于此列允许的指定精度的完整错误描述,它只抛出一般错误,没有捕获列名和大小。任何变通方法都可以与此代码集成,以获得与错误相关联的完整列描述 create or replace procedure BULK_COLLECT_TEST_PROC as TYPE t_bulk_collect_test_tab IS TABLE OF bulk_collect_test%ROWTYPE; l_tab t_bulk_co
create or replace procedure BULK_COLLECT_TEST_PROC
as
TYPE t_bulk_collect_test_tab IS TABLE OF bulk_collect_test%ROWTYPE;
l_tab t_bulk_collect_test_tab;
l_error_count NUMBER;
ex_dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(ex_dml_errors, -24381);
CURSOR c_data IS
SELECT *
FROM bulk_collect_test;
BEGIN
OPEN c_data;
LOOP
FETCH c_data
BULK COLLECT INTO l_tab LIMIT 10000;
EXIT WHEN l_tab.count = 0;
-- Perform a bulk operation.
BEGIN
FORALL i IN l_tab.first .. l_tab.last SAVE EXCEPTIONS
INSERT INTO exception_test
VALUES l_tab(i);
EXCEPTION
WHEN ex_dml_errors THEN
l_error_count := SQL%BULK_EXCEPTIONS.count;
DBMS_OUTPUT.put_line('Number of failures: ' || l_error_count);
FOR i IN 1 .. l_error_count LOOP
DBMS_OUTPUT.put_line('Error: ' || i ||
' Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;
END LOOP;
END;
/
SET SERVEROUTPUT ON;
EXEC BULK_COLLECT_TEST_PROC;
Number of failures: 9001
Error: 1 Array Index: 1000 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 2 Array Index: 1001 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 3 Array Index: 1002 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 4 Array Index: 1003 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 5 Array Index: 1004 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 6 Array Index: 1005 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 7 Array Index: 1006 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 8 Array Index: 1007 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 9 Array Index: 1008 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 10 Array Index: 1009 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 11 Array Index: 1010 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 12 Array Index: 1011 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 13 Array Index: 1012 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 14 Array Index: 1013 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 15 Array Index: 1014 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 16 Array Index: 1015 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 17 Array Index: 1016 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 18 Array Index: 1017 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 19 Array Index: 1018 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 20 Array Index: 1019 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 21 Array Index: 1020 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 22 Array Index: 1021 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 23 Array Index: 1022 Message: ORA-01438: value larger than specified precision allowed for
this column
Error: 24 Array Index: 1023 Message: ORA-01438: value larger than specified precision allowed for
this column
正如甲骨文所说
需要时,将SaveExceptions子句添加到FORALL语句中
执行由生成的所有DML语句的PL/SQL运行时引擎
FORALL,即使一个或多个错误失败。如果你使用
当然,你需要注意找到返回的方法
令人不快的陈述
因此,SAVE异常正在执行它应该执行的操作,因此在结束之前完全运行整个FORALL,而不会引发任何问题。这里的问题是ORA-01438:值大于此列允许的指定精度
。这个例外永远不会通知受影响的专栏。为了捕获有问题的列,您有一些选项
SQL
在SQL中,例如使用sqlplus,您会得到一个指示,指示哪个列负责,因为它由一个星号标记,尽管该列在异常中没有显式命名
SQL> create table t ( c1 number(1) , c2 number(2) , c3 number(3) ) ;
Table created.
SQL> insert into t values ( 1 , 22, 3333 ) ;
insert into t values ( 1 , 22, 3333 )
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
PL/SQL
在PL/SQL中,异常由异常模块处理,该模块控制与错误相关联的SQLCODE和SQLERRM。在该错误中,没有任何关于列的指示:
SQL> declare
2 begin
3 insert into t values ( 1 , 22, 3333 );
4 commit;
5 end;
6 /
declare
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at line 3
在这种情况下,您可能会得到帮助,但在出现异常时会显示这些值
SQL> declare
2 v_1 number := 1;
3 v_2 number := 22;
4 v_3 number := 3333;
5 begin
6 insert into t values ( v_1 , v_2, v_3) ;
7 commit;
8 exception when others then
9 dbms_output.put_line( v_1 || '-' || v_2 || '-' || v_3 );
10 raise;
11* end;
SQL> /
1-22-3333
declare
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at line 10
ORA-06512: at line 6
DML错误日志记录
DML错误记录
是一项非常适合您的场景的功能。创建错误表后,必须应用子句将错误记录到错误表中
范例
SQL> EXEC DBMS_ERRLOG.CREATE_ERROR_LOG (DML_TABLE_NAME => 'T' , err_log_table_name => 'T_ERRORS' ) ;
PL/SQL procedure successfully completed.
declare
v_1 number := 1;
v_2 number := 22;
v_3 number := 3333;
begin
insert into t values ( v_1 , v_2, v_3) log errors into t_errors;
commit;
exception when others then
raise;
end;
/
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at line 10
ORA-06512: at line 6
SQL> col c1 for a10
SQL> col c2 for a10
SQL> col c3 for a10
SQL> select ORA_ERR_NUMBER$,ORA_ERR_MESG$,c1,c2,c3 from t_errors ;
ORA_ERR_NUMBER$
---------------
ORA_ERR_MESG$
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C1 C2 C3
---------- ---------- ----------
1438
ORA-01438: value larger than specified precision allowed for this column
1 22 3333
在特定代码中,您必须:
1.使用DBMS\u ERRLOG为异常测试表创建错误表
EXEC DBMS_ERRLOG.CREATE_ERROR_LOG (DML_TABLE_NAME => 'EXCEPTION_TEST' , err_log_table_name => 'T_ERR_EXCEPTION_TEST' );
2.更改INSERT语句,将子句记录错误添加到\u ERROR\u表中
,并删除保存异常
部分。使用DML_错误记录后,所有异常都将保存在错误记录表中
FORALL i IN l_tab.first .. l_tab.last
INSERT INTO exception_test
VALUES l_tab(i) log errors into T_ERR_EXCEPTION_TEST;
更新
代码的变体
EXEC DBMS_ERRLOG.CREATE_ERROR_LOG (DML_TABLE_NAME => 'EXCEPTION_TEST' , err_log_table_name => 'T_ERR_EXCEPTION_TEST' );
create or replace procedure BULK_COLLECT_TEST_PROC
as
TYPE t_bulk_collect_test_tab IS TABLE OF bulk_collect_test%ROWTYPE;
l_tab t_bulk_collect_test_tab;
l_error_count NUMBER;
CURSOR c_data IS
SELECT *
FROM bulk_collect_test;
BEGIN
-- first truncate error table
execute immediate ' truncate table T_ERR_EXCEPTION_TEST drop storage ' ;
-- collection and insert
OPEN c_data;
LOOP
FETCH c_data
BULK COLLECT INTO l_tab LIMIT 10000;
EXIT WHEN l_tab.count = 0;
-- Perform a bulk operation.
BEGIN
FORALL i IN l_tab.first .. l_tab.last
INSERT INTO exception_test VALUES l_tab(i) log errors into T_ERR_EXCEPTION_TEST ;
END LOOP;
-- count errors
commit ;
select count(*) into l_error_count from T_ERR_EXCEPTION_TEST;
if l_error_count > 0
then
-- loop over the errors if you want to here by selecting the error
-- table
null;
end if;
EXCEPTION
WHEN OTHERS THEN RAISE;
END;
END LOOP;
END;
/
正如甲骨文所说
需要时,将SaveExceptions子句添加到FORALL语句中
执行由生成的所有DML语句的PL/SQL运行时引擎
FORALL,即使一个或多个错误失败。如果你使用
当然,你需要注意找到返回的方法
令人不快的陈述
因此,SAVE异常正在执行它应该执行的操作,因此在结束之前完全运行整个FORALL,而不会引发任何问题。这里的问题是ORA-01438:值大于此列允许的指定精度
。这个例外永远不会通知受影响的专栏。为了捕获有问题的列,您有一些选项
SQL
在SQL中,例如使用sqlplus,您会得到一个指示,指示哪个列负责,因为它由一个星号标记,尽管该列在异常中没有显式命名
SQL> create table t ( c1 number(1) , c2 number(2) , c3 number(3) ) ;
Table created.
SQL> insert into t values ( 1 , 22, 3333 ) ;
insert into t values ( 1 , 22, 3333 )
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
PL/SQL
在PL/SQL中,异常由异常模块处理,该模块控制与错误相关联的SQLCODE和SQLERRM。在该错误中,没有任何关于列的指示:
SQL> declare
2 begin
3 insert into t values ( 1 , 22, 3333 );
4 commit;
5 end;
6 /
declare
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at line 3
在这种情况下,您可能会得到帮助,但在出现异常时会显示这些值
SQL> declare
2 v_1 number := 1;
3 v_2 number := 22;
4 v_3 number := 3333;
5 begin
6 insert into t values ( v_1 , v_2, v_3) ;
7 commit;
8 exception when others then
9 dbms_output.put_line( v_1 || '-' || v_2 || '-' || v_3 );
10 raise;
11* end;
SQL> /
1-22-3333
declare
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at line 10
ORA-06512: at line 6
DML错误日志记录
DML错误记录
是一项非常适合您的场景的功能。创建错误表后,必须应用子句将错误记录到错误表中
范例
SQL> EXEC DBMS_ERRLOG.CREATE_ERROR_LOG (DML_TABLE_NAME => 'T' , err_log_table_name => 'T_ERRORS' ) ;
PL/SQL procedure successfully completed.
declare
v_1 number := 1;
v_2 number := 22;
v_3 number := 3333;
begin
insert into t values ( v_1 , v_2, v_3) log errors into t_errors;
commit;
exception when others then
raise;
end;
/
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at line 10
ORA-06512: at line 6
SQL> col c1 for a10
SQL> col c2 for a10
SQL> col c3 for a10
SQL> select ORA_ERR_NUMBER$,ORA_ERR_MESG$,c1,c2,c3 from t_errors ;
ORA_ERR_NUMBER$
---------------
ORA_ERR_MESG$
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C1 C2 C3
---------- ---------- ----------
1438
ORA-01438: value larger than specified precision allowed for this column
1 22 3333
在特定代码中,您必须:
1.使用DBMS\u ERRLOG为异常测试表创建错误表
EXEC DBMS_ERRLOG.CREATE_ERROR_LOG (DML_TABLE_NAME => 'EXCEPTION_TEST' , err_log_table_name => 'T_ERR_EXCEPTION_TEST' );
2.更改INSERT语句,将子句记录错误添加到\u ERROR\u表中
,并删除保存异常
部分。使用DML_错误记录后,所有异常都将保存在错误记录表中
FORALL i IN l_tab.first .. l_tab.last
INSERT INTO exception_test
VALUES l_tab(i) log errors into T_ERR_EXCEPTION_TEST;
更新
代码的变体
EXEC DBMS_ERRLOG.CREATE_ERROR_LOG (DML_TABLE_NAME => 'EXCEPTION_TEST' , err_log_table_name => 'T_ERR_EXCEPTION_TEST' );
create or replace procedure BULK_COLLECT_TEST_PROC
as
TYPE t_bulk_collect_test_tab IS TABLE OF bulk_collect_test%ROWTYPE;
l_tab t_bulk_collect_test_tab;
l_error_count NUMBER;
CURSOR c_data IS
SELECT *
FROM bulk_collect_test;
BEGIN
-- first truncate error table
execute immediate ' truncate table T_ERR_EXCEPTION_TEST drop storage ' ;
-- collection and insert
OPEN c_data;
LOOP
FETCH c_data
BULK COLLECT INTO l_tab LIMIT 10000;
EXIT WHEN l_tab.count = 0;
-- Perform a bulk operation.
BEGIN
FORALL i IN l_tab.first .. l_tab.last
INSERT INTO exception_test VALUES l_tab(i) log errors into T_ERR_EXCEPTION_TEST ;
END LOOP;
-- count errors
commit ;
select count(*) into l_error_count from T_ERR_EXCEPTION_TEST;
if l_error_count > 0
then
-- loop over the errors if you want to here by selecting the error
-- table
null;
end if;
EXCEPTION
WHEN OTHERS THEN RAISE;
END;
END LOOP;
END;
/
我贴了一个答案,上面有一个很大的解释。如果你对此有任何疑问,请告诉我。我会在上面贴一个答案,并给出一个非常详细的解释。如果您对itI有任何疑问,请告诉我。我尝试过这种方法,但批量收集或内部循环都不可能。@VishwasMohan;我将发布更新。必须删除保存异常,如果使用DML_ERROR_LOGGINGexec dbms_errlog,则没有任何意义。创建_ERROR_log(DML_table_name=>'exception_test',err_log_table_name=>'exception_test_errors');首先开始l_选项卡中的所有i。。l_选项卡。上次保存异常插入异常测试值l_选项卡(i)将错误记录到异常测试错误中;从命令中的第13行开始时出错-开始批量收集测试过程;结束;错误报告-ORA-38909:批处理错误模式ORA-06512:在“testschema.BULK\u COLLECT\u TEST\u PROC”的第23行ORA-06512:在第1行,不支持DML错误日志记录。@VishwasMohan,我无法测试您的场景。我发布了一个新的变体,但是您必须删除异常和save_异常。DML错误记录不会引起任何问题,它会将错误记录在一个表中。在我的新答案中,你必须填写你想做的任何事情,以防错误表中记录了错误。我尝试了这种方法,但在批量收集或内部循环中是不可能的。@VishwasMohan;我将发布更新。必须删除保存异常,如果使用DML_ERROR_LOGGINGexec dbms_errlog,则没有任何意义。创建_ERROR_log(DML_table_name=>'exception_test',err_log_table_name=>'exception_test_errors');首先开始l_选项卡中的所有i。。l_选项卡。上次保存异常插入异常测试值l_选项卡(i)将错误记录到异常测试错误中;从co中的第13行开始时出错