Oracle:为什么我必须使用 TO_DATE 来提取数据?

Oracle: Why do I have to use TO_DATE to pull my data?

尝试过滤 EXPIRE_DATE 时,我似乎必须使用 TO_DATE。为什么我必须使用 TO_DATE?数据库中的 EXPIRE_DATE 数据类型已设置为最新。这是有效的代码。

SELECT * FROM MY_TABLE
  WHERE EXPIRE_DATE >= TO_DATE('2020/01/13','yyyy/mm/dd')
  AND EXPIRE_DATE <= TO_DATE('2020/04/19','yyyy/mm/dd')

我尝试在没有 TO_DATE 的情况下使用 BETWEEN 并仅使用我的日期,但我收到错误消息。

总而言之,即使此数据类型是 ALREADY 日期,但似乎我必须在要过滤时使用 TO_DATE 来提取数据。有什么我想念的吗?这是我在不使用 TO_DATE.

的情况下尝试过滤数据时的错误

您不需要使用 TO_DATE,而是可以使用 DATE 文字:

SELECT *
FROM   MY_TABLE
WHERE  EXPIRE_DATE >= DATE '2020/01/13'
AND    EXPIRE_DATE <= DATE '2020/04/19'

或者,如果您的 NLS_DATE_FORMAT 会话参数与 YYYY/MM/DD 匹配,那么您可以将值作为字符串插入并依赖于隐式字符串转换(尽管不要这样做):

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MM/DD';

SELECT *
FROM   MY_TABLE
WHERE  EXPIRE_DATE >= '2020/01/13'
AND    EXPIRE_DATE <= '2020/04/19'

但是依赖 NLS_DATE_FORMAT 并不是好的做法,因为 ANY 用户可以在 ANY 处更改自己的值这样当用户开始更改这些值时,您的查询可能会随机失败。

您可以使用 BETWEEN:

警告:最好始终使用具有正确格式字符串的TO_DATE函数,避免某些情况下的隐式转换在结果中产生奇怪的行为。

警告:所有 DATE 类型的列始终包含小时-分钟-秒组件。 如果您忘记了这一点,结果中的记录可能会更少。

示例:

create table my_table
(id          number,
 expire_date date
);

一些数据:

insert into my_table values ( 4,to_date('2011-06-17 10:07:18','yyyy-mm-dd hh24:mi:ss')); 
insert into my_table values (12,to_date('2010-10-01 17:43:30','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (13,to_date('2011-07-30 08:38:34','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (21,to_date('2010-04-22 07:03:35','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (26,to_date('2011-03-26 02:07:57','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (35,to_date('2010-09-16 17:40:01','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (38,to_date('2011-11-05 17:27:45','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (44,to_date('2011-12-25 04:51:24','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (45,to_date('2011-11-05 03:08:51','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (54,to_date('2011-09-22 18:29:14','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (78,to_date('2010-03-12 20:23:21','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (79,to_date('2011-05-19 17:30:15','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (83,to_date('2011-11-15 10:04:58','yyyy-mm-dd hh24:mi:ss'));
insert into my_table values (96,to_date('2011-03-11 20:14:30','yyyy-mm-dd hh24:mi:ss'));

将默认日期格式设置为 ISO-8601 国际格式:

alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';

使用隐式转换的查询:

SELECT a.*
fROM my_table a
where expire_date between '2010-01-01 00:00:00'
                      and '2010-12-31 23:59:59';

答案:

ID EXPIRE_DATE        
12 2010-10-01 17:43:30
21 2010-04-22 07:03:35
35 2010-09-16 17:40:01
78 2010-03-12 20:23:21

但使用美国日期格式月-日-年:

SELECT a.*
fROM my_table a
where expire_date between '01/01/2010 00:00:00'
                      and '12/31/2010 23:59:59';

你遇到错误:

ORA-01861: literal does not match format string

将会话日期格式更改为美国格式:

alter session set nls_date_format='MM-DD-YYYY HH24:MI:SS';

你可以用美国格式写日期:

SELECT a.*
fROM my_table a
where expire_date between '01/01/2010 00:00:00'
                      and '12/31/2010 23:59:59';

答案是:

        ID EXPIRE_DATE
---------- -------------------
        12 10-01-2010 17:43:30
        21 04-22-2010 07:03:35
        35 09-16-2010 17:40:01
        78 03-12-2010 20:23:21

除了这里的一些好的答案,我想告诉你,你不需要 TO_DATE 从你的 table.

中提取数据

您需要 to_datedate literal 将普通字符串转换为可以与 table 中的列数据进行比较的日期,因为日期列必须与日期数据类型 variable/constant.

要将普通字符串转换为日期,您可以使用以下方法:

TO_DATE('2020/01/13','yyyy/mm/dd')
DATE '2020-01-13'

我不建议仅使用 NLS_DATE_FORMAT 创建日期。