奇怪的Oracle日期行为

Igo*_*cic 2 sql oracle

我的一个生产数据库中有一个奇怪的问题.长话短说,简单查询:

select id, trunc(stdate) from table_name where trunc(stdate) = '05-FEB-09';  
Run Code Online (Sandbox Code Playgroud)

没有返回任何行.然而,

select trunc(stdate) from table_name where id = sought_after_id;
Run Code Online (Sandbox Code Playgroud)

回来了'05-FEB-09'.只有在我尝试之后:

update table_name set stdate = '05-FEB-09' where id = sought_after_id;
Run Code Online (Sandbox Code Playgroud)

我的原始查询按预期工作:

select id, trunc(stdate) from table_name where trunc(stdate) = '05-FEB-09';
> sought_after_id, '05-FEB-09'
Run Code Online (Sandbox Code Playgroud)

那么,我的标准值发生了什么?

Vin*_*rat 5

你应该总是将日期与日期(苹果到苹果......)进行比较,而不是依赖隐式转换.

由于TRUNC(date)返回日期,您应该将其与日期进行比较:

select id, trunc(stdate) from table_name where trunc(stdate) = DATE '2009-02-05'
Run Code Online (Sandbox Code Playgroud)

要么

select id, trunc(stdate) 
  from table_name 
 where trunc(stdate) = TO_DATE('05-FEB-09', 'DD-MON-RR'))
Run Code Online (Sandbox Code Playgroud)

更新回应伊戈尔的第一条评论:

依赖隐式数据转换会使查询结果依赖于多个会话参数.如果您现在看到前几天的不同结果,则必须修改其中一个参数.您可以通过不依赖隐式转换使查询"与会话无关".

值得坚持的是,您的第一个查询取决于客户端会话的参数.如果会话修改其默认日期显示设置,则 NLS_DATE_FORMAT查询将不会返回相同的结果.

在相关的说明中,这DD-MON-RR是一个完全可以接受的显示日期格式,但它不适合在您的代码中使用,因为存在关于世纪的歧义并且您依赖于NLS_DATE_LANGUAGE参数的月份.

  • @Igor您的查询已运行5年以上.我想你还有其他问题;-) (4认同)