【问题标题】:ORA-01847 day of month must be between 1 and last day of month - but data is OKORA-01847 日期必须介于 1 和最后一天之间 - 但数据正常
【发布时间】:2014-04-21 18:57:23
【问题描述】:

问题已解决 - 请参阅本文结尾。

当我在 select 子句中调用 to_date 时,一切正常 - 获得 12 条记录的结果集:

select value1,to_date(value1,'DD.MM.YYYY') 
  from variableindex 
  where 
    value1 is not null 
    and value1 <> '0' 
    and creation_time_ > to_timestamp('20140307','YYYYMMDD')
  order by 2

返回

'VALUE1'     'TO_DATE(VALUE1,'DD.MM.YYYY')'
'25.11.2013' 25.11.13
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'12.03.2014' 12.03.14
'14.03.2014' 14.03.14
'14.03.2014' 14.03.14
'14.03.2014' 14.03.14
'14.03.2014' 14.03.14
'20.03.2014' 20.03.14
'20.03.2014' 20.03.14

每个日期字符串都已按预期转换。

如果我将以下行添加到 where 子句

and to_date(value1,'DD.MM.YYYY') < to_date('20140301','YYYYMMDD')

我会收到:

ORA-01847: Tag des Monats muss zwischen 1 und letztem Tag des Monats liegen
01847. 00000 -  "day of month must be between 1 and last day of month"
*Cause:    
*Action:

不,它真的很讨厌...我将查询更改为

where id_ in (...)

并使用与原始查询相同的 12 个记录集 ID。没有错误...

非常感谢@GordonLinoff - 这就是我现在使用查询的方式:

select value1,to_date(value1,'DD.MM.YYYY') from variableindex 
   where 
   (case when value1 <> '0'  then to_date(value1,'DD.MM.YYYY') end) >  to_timestamp('20131114','YYYYMMDD')
   and creation_time_ > to_timestamp('20140307','YYYYMMDD')
order by 2;

【问题讨论】:

  • 尝试 select to_date('20140301','YYYYMMDD') from dual 并检查输出
  • 我想知道为什么它应该在 select 子句中起作用,而不是在 where 子句中
  • @Joggl 。 . .这真的是表中的所有数据吗?
  • @GordonLinoff 没有,但它是使用“and creation_time_ > to_timestamp('20140307','YYYYMMDD')”时的所有内容
  • 这是因为过滤器value1 &lt;&gt; '0' 可能会在您转换to_date(value1,'DD.MM.YYYY') 之后应用。可能,这是 Oracle 的“功能”,看起来像一个错误。

标签: sql oracle date


【解决方案1】:

如果您在 SQL 中使用OracleParameter 与参数名称和值绑定,请检查您设置了oracleCommand.BindByName = true,然后它将按名称绑定,而不是按参数添加顺序。

【讨论】:

    【解决方案2】:

    这是您使用 where 子句的查询:

    select value1, to_date(value1,'DD.MM.YYYY') 
    from variableindex 
    where value1 is not null and
          value1 <> '0' and
          creation_time_ > to_timestamp('20140307', 'YYYYMMDD') and
          to_date(value1 'DD.MM.YYYY') < to_date('20140301', 'YYYYMMDD')
    order by 2;
    

    Oracle 不保证where 中子句的处理顺序。因此,value &lt;&gt; '0' 不能保证在最后一个条件之前运行。这恰好是 SQL Server 上的一个大问题。一种解决方案是使用case 语句:

    select value1,to_date(value1, 'DD.MM.YYYY') 
    from variableindex 
    where value1 is not null and
          value1 <> '0' and
          creation_time_ > to_timestamp('20140307', 'YYYYMMDD') and
          (case when value <> '0' then to_date(value1, 'DD.MM.YYYY') end) <
              to_date('20140301', 'YYYYMMDD')
    order by 2;
    

    相当丑陋,但它可能会解决你的问题。

    【讨论】:

    • 普通人 - 你做到了!
    • +1 @Joggl 怀疑这一点,但你对 previous question 的评论让我措手不及。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多