【问题标题】:ORA-01847 - SELECT returns no resultORA-01847 - SELECT 不返回结果
【发布时间】:2017-10-24 21:27:57
【问题描述】:

我在 OFO 架构中有一个表 TIGER。

我有一个数据类型为 DATE 的列 AS_OF_DATE。

我在此列中的值如下:

2017-01-31 00:00:00
2017-02-28 00:00:00
2017-03-31 00:00:00

但我也有 1 个不需要的值(我想删除,但我想先通过 sql 语句 SELECT 它):

 0030-09-20 17:00:00

我使用 TOAD 在模式浏览器中查看这些值。

我也可以使用 select 来返回值,这个可行,它返回结果:

SELECT AS_OF_DATE from OFO.TIGER where AS_OF_DATE='2017-01-31'

但是下面的选择不起作用:

SELECT AS_OF_DATE from OFO.TIGER where AS_OF_DATE='0030-09-20'

它给了我一个错误:

ORA-01847: 月份中的某天必须介于 1 和最后一天之间 提示

日期显然格式错误,但不知何故有人设法添加了该值,现在我想删除它(所有具有AS_OF_DATE='0030-09-20' 的行)。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您的查询依赖于邪恶的隐式数据类型转换。 '2017-01-31' 是字符串常量不是 DATE 常量。此转换的规则由 客户端 的 NLS 设置定义。

    您有两种方法可以在 Oracle 中指定正确的 DATE 常量:

    使用 ANSI SQL 日期文字

    SELECT * 
    FROM ofo.tiger 
    WHERE as_of_date = DATE '2017-01-31';
    

    SELECT * 
    FROM ofo.tiger 
    WHERE as_of_date = DATE '0030-09-20';
    

    ANSI DATE 文字 always 以 ISO 格式 yyyy-mm-dd 指定 DATE,因此没有关于 1930 与 2030 的隐式转换规则

    使用Oracle的to_date()函数:

    SELECT * 
    FROM ofo.tiger 
    WHERE as_of_date = to_date('0030-09-20', 'YYYY-MM-DD');
    

    通过指定format mask,年份也是明确的,不会发生隐式转换。

    【讨论】:

    • 感谢您不仅提供了解决方案,还提供了清晰的解释。现在它按预期工作了......你的答案是最准确的,虽然 JohnHC 也给了我相同的结果,但它不是那么准确。
    • @korodani:如果答案解决了您的问题,请接受。这样您的问题就会被标记为已解决。
    【解决方案2】:

    我会按如下方式编写查询,TRUNC 语句只会从 datetime 列中提取日期,它会正确地满足您的需要:

    SELECT * 
    from ofo.tiger 
    where TRUNC(as_of_date) = TRUNC(to_date('0030-09-20', 'YYYY-MM-DD'));
    

    【讨论】:

      【解决方案3】:

      不要选择它是什么,而是选择它不是什么:

      select AS_OF_DATE
      from OFO.TIGER
      where not AS_OF_DATE between '1970-01-01' and '2017-12-31'
      

      【讨论】:

        猜你喜欢
        • 2016-01-28
        • 2020-12-04
        • 2014-07-10
        • 1970-01-01
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-23
        相关资源
        最近更新 更多