ORA-01847 - SELECT不返回结果

时间:2017-10-24 09:08:50

标签: sql oracle

我在模式OFO中有一个TIGER表。

我有一个AS_OF_DATE列,数据类型为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在Schema Browser中查看这些值。

我也可以使用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'的行。)

3 个答案:

答案 0 :(得分:4)

您的查询依赖于邪恶的隐式数据类型转换。 '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文字始终指定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,年份也是不明显的,不会进行隐式转换。

答案 1 :(得分:0)

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

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

答案 2 :(得分:-1)

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

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