Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 保存异常未捕获ORA-01438的完整错误描述_Oracle_Plsql_Oracle11g_Bulk Collect - Fatal编程技术网

Oracle 保存异常未捕获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

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_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行开始时出错