我在模式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'
的行。)
答案 0 :(得分:4)
您的查询依赖于邪恶的隐式数据类型转换。 '2017-01-31'
是字符串常量不 DATE
常量。此转换的规则由客户端的NLS设置定义。
在Oracle中有两种方法可以指定正确的DATE常量:
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年的隐式转换规则
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'