1

oracle ora-01722更新语句中的无效数字 where 子句。我想在错误日志表中记录这个错误。我怎样才能登录??下面是我的更新声明,这里 empid 是数字。

UPDATE SARVESH_TEST_ERR_TB
SET    empid = empid
WHERE  empid ='aaa'
LOG ERRORS INTO SARVESH_ERR_LOGS_TB ('Error while UPDATE') 
REJECT LIMIT UNLIMITED;
4

1 回答 1

2

您不能(不会记录错误)使用 DML 语句的错误日志记录子句来记录 DML 语句WHERE子句中引发的错误。update基本上,包含子句的DML(例如您的语句)where由两部分组成,写入部分和读取一个 - 所以where子句是读取部分(基本上是选择/光标),您可以使用错误日志记录子句仅捕获写入部分的错误的 DML 语句引发。为了能够捕获该错误并将其写入错误记录表,您可以使用after servererror触发器,但您将无法抑制该错误:

/* test table */
SQL> create table tb_erp(
  2    col number
  3  )
  4  /
Table created

/* simple error logging table */
SQL> create table error_logs(
  2    msg varchar2(123)
  3  )
  4  /
Table created

SQL> insert into tb_erp(col) values(1);
1 row inserted

SQL> commit;
Commit complete

SQL> create or replace trigger TR_CATCH_ERRORS
  2  after servererror on schema
  3  begin
  4    insert into error_logs(msg)
  5      values(ora_server_error_msg(1));
  6  end;
  7  /
Trigger created

测试用例:

SQL> update tb_erp t 
        set t.col = 5 
      where t.col = 'aaa';

update tb_erp t set t.col = 5 where t.col = 'aaa'
ORA-01722: invalid number

/* view errors */
SQL> select * 
  2    from error_logs;

MSG
-------------------------------
ORA-01722: invalid number

编辑#1

但我必须记录错误消息,错误值('aaa'),创建日期/错误日期,是否是插入/更新语句 结果集将是 Ora-01722:invalidnumber 'aaa' 23-oct-2013 'exception on插入/更新'。有没有这样的选择

对于这个特定的错误,您将无法提取实际值('aaa'),但您可以做的是记录导致错误的整个 DML 语句:

When触发器的子句允许您列出要触发的错误,否则它将因引发的任何错误而触发。

SQL> alter table error_logs add ( text     varchar2(4000)
  2                             , timestmp timestamp )
  3  ;
Table altered


create or replace trigger TR_CATCH_ERRORS
after servererror on schema
--when ( ora_server_error(1) in ('1722') )
declare
  l_sql_txt_list ora_name_list_t;
  l_elements     binary_integer;
  l_sql_txt      varchar2(4000);

begin
  /* if statement triggering an error is long
    it'll be broken into several pieces and
    in order to get a complete statamet we have to assemble 
    those pieces */
  l_elements := ora_sql_txt(l_sql_txt_list);

  for i in 1..l_elements
  loop
    l_sql_txt := l_sql_txt || l_sql_txt_list(i);
  end loop;
  insert into error_logs(msg, text, timestmp)
    values( ora_server_error_msg(1)
           , l_sql_txt
           , systimestamp );
end; 

测试用例:

SQL> update tb_erp t set t.col = 5 where t.col = 'aaa';
update tb_erp t set t.col = 5 where t.col = 'aaa'
ORA-01722: invalid number

/* view errors */

SQL> select * from error_logs;

 MSG                        TEXT                     TIMESTMP
 ---------------------------------------------------------------------------
 ORA-01722: invalid number  update tb_erp t     23-OCT-13 11.04.57.535000 AM
                               set t.col = 5 
                             where t.col = 'aaa'
于 2013-10-23T06:14:22.147 回答