to_date(sysdate
不要在 DATE 上使用 TO_DATE。它会强制 Oracle 进行以下操作:
这是基于特定于区域设置的 NLS 设置。您需要使用 TO_DATE 将文字转换为日期。对于日期算术运算,请保留日期不变。
SQL> SELECT to_char(to_date('27-OCT-2015', 'DD-MON-YYYY'), 'DAY') FROM dual;
TO_CHAR(T
TUESDAY
根本原因
SQL> alter session set nls_date_format='DD-MON-RR';
Session altered.
SQL> select to_char(to_date(sysdate,'DD-MON-YYYY'),'DD-MON-YYYY') from dual;
TO_CHAR(TO_
27-OCT-0015
所以这一年被改为0015
。因为你将已经是DATE
类型的值从RR格式转换为YYYY格式。
现在,0015年10月27日是一个星期天。
SQL> select to_char(to_date('27-OCT-0015','DD-MON-YYYY'),'DAY') FROM DUAL;
TO_CHAR(T
SUNDAY
为了理解内部行为,让我们看一个小演示:
SQL> SET AUTOT ON EXPLAIN
SQL> SELECT * FROM dual WHERE SYSDATE = TO_DATE(SYSDATE);
no rows selected
Execution Plan
Plan hash value: 3752461848
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter(SYSDATE@!=TO_DATE(TO_CHAR(SYSDATE@!)))
你看到了
filter(SYSDATE@!=TO_DATE(TO_CHAR(SYSDATE@!)))
。 这个过滤器发生了什么?
在
SYSDATE上使用
TO_DATE会在内部被解释为
TO_DATE(TO_CHAR(SYSDATE@!))
。
所以,首先应用
TO_CHAR,它的格式取决于您本地的
NLS_DATE_FORMAT,然后将其转换回
DATE。
更新 基于下面的评论...
使用:
- TO_DATE 将日期字面值(字符串)转换为DATE。由于TO_DATE是NLS相关的,我更喜欢在每个语句级别明确指定格式和NLS_DATE_LANGUAGE。
SQL> alter session set nls_date_format='YYYY-MM-DD';
Session altered.
SQL> SELECT TO_DATE('27-OCT-2015', 'DD-MON-YYYY','NLS_DATE_LANGUAGE=ENGLISH')
2 FROM DUAL;
TO_DATE('2
----------
2015-10-27
如果您依赖
客户端的NLS设置,那么对于在
不同位置使用不同NLS的人可能无法正常工作。
SQL> alter session set NLS_DATE_LANGUAGE='FRENCH';
Session altered.
SQL> SELECT TO_DATE('27-OCT-2015', 'DD-MON-YYYY') from dual;
SELECT TO_DATE('27-OCT-2015', 'DD-MON-YYYY') from dual
*
ERROR at line 1:
ORA-01843: not a valid month
- TO_CHAR函数将日期转换为字符串,以所需格式显示,使用适当的格式模板。
不要反过来做。
to_date
返回的是一周中的第一天 -星期日
。 - Nguyễn Hải Triềuto_date(sysdate
?真的吗?sysdate已经是一个日期,你不需要将日期强制转换为日期。 - Stawros