【问题标题】:Oracle DML Error Logging field typeOracle DML 错误日志记录字段类型
【发布时间】:2015-08-18 10:36:32
【问题描述】:

我想问一下 Oracle 中的 DML 错误记录 我有一个具有这种结构的原始表

table_test(
ID Int PK,
test_time date
)

我还为此创建了一个错误记录表 ERR$_table_test

据我所知,ERR$_table_test 中的字段 'ID' 和 'test_time'VARCHAR(4000)

举个例子

1. Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) 

==> 成功,插入 1 行

2. Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss'))

==> 在 table_test 中插入 0 行,在 ERR$_table_test 中插入 1 行,但出现此错误:ORA-00001:违反唯一约束

3. select * from ERR$_table_test

找到 1 条记录:但字段 test_time 是 '18/08/2015' 没有时间

之后,我尝试更改表 ERR$_table_test

alter table ERR$_table_test modify test_time date

我重做上面的例子

这次我得到了 ERR$_table_test 中 test_time 的完整时间戳

但是,那我试试

Insert into table_test values (2,to_date('abc xyz' , 'dd/mm/yyyy hh24:mi:ss'))

==> 在 ERR$_table_test 中插入错误类型时发生 SQL 错误

这是我关心的事情

  1. 我能否在不更改列类型的情况下在 ERR$_table_test 中获得完整的时间戳?

  2. 如果我必须将列类型更改为 DATE,当时间格式错误时,我是否仍会收到第二种情况的错误日志?

感谢您的支持,

【问题讨论】:

  • 您是否尝试在插入之前在会话中运行alter session set nls_date_format = 'dd/mm/yyyy hh24:mi:ss');

标签: database oracle logging dml


【解决方案1】:

如果它可以评估日期,那么它将使用您的会话设置将其转换回字符串以放入varchar2(4000) 列。由于它是一个日期字段,您可以通过在执行插入之前设置 NLS_DATE_FORMAT 来控制它:

alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';

Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test;

Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test;

Insert into table_test values (2,to_date('abc xyz' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test;

column id format a10
column test_time format a20
select ora_err_number$, id, test_time from ERR$_table_test;

                        ORA_ERR_NUMBER$ ID         TEST_TIME          
--------------------------------------- ---------- --------------------
                                      1 1          2015-08-18 15:00:00 
                                   1858 2          abc xyz        

这并不理想,尤其是当您可能从多个客户端插入时,您无法控制其设置。

但正如the documentation 所指出的,如果您在错误记录表中使用日期数据类型而不是推荐的(默认,如果通过DBMS_ERRLOG 创建)varchar2(4000),则转换失败 - 与您的@987654326 一样@value - 会导致整个语句失败:

由于类型转换错误是可能发生的错误类型之一,因此错误记录表中可选列的数据类型必须是可以捕获任何值而不会丢失数据或转换错误的类型。 (如果可选的日志列与 DML 表列的类型相同,则将有问题的数据捕获到日志中可能会遇到导致错误的相同数据转换问题。)数据库会尽最大努力为数据记录有意义的值这会导致转换错误。如果无法导出值,则为该列记录 NULL。插入错误记录表时出错会导致语句终止。

所以回答你的第二个问题,不;如果您将错误日志数据类型更改为 DATE,那么您将不会收到针对无效日期/时间格式的错误记录,该语句将终止。

【讨论】:

  • 谢谢,我试过了,它可以工作,但是除了更改当前会话的 nls_date_format 之外还有其他选择吗,因为我的 SQL 语句将与其他人一起在脚本中自动运行,所以我担心这个更改可能影响他人
  • @mrzenky - 你的脚本中不应该有任何依赖 NLS_DATE_FORMAT 的东西。这就是为什么这并不理想,因为它增加了这种依赖;但由于 Oracle 正在进行隐式转换,我看不到任何其他方法。我想您可以捕获并重置原始设置;但这并没有真正的意义,除非您只有几条启用了错误日志记录的语句。
猜你喜欢
  • 2016-10-31
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 2022-10-20
  • 2013-06-30
相关资源
最近更新 更多