select to_char(sysdate, 'DAY') from dual;
将正确返回 TUESDAY
。
但是为什么当我在同一天运行 select to_char(to_date(sysdate, 'DD-MON-YYYY'), 'DAY') from dual;
时,它返回 SUNDAY
?
由于在尝试运行 ORA-01835: day of week conflicts with Julian date
时出现 select to_date('27-OCT-15', 'D') from dual;
错误,在尝试从中获取星期几之前,我必须最终将日期(我动态传递给函数的)转换为 DD-MON-YYYY
格式。有谁知道为什么我看到这种不一致?
一个更好的例子在这里(我已经替换了例子中的列名和表名)。
SELECT DATE,
to_char(DATE, 'DAY'),
to_char(to_date(DATE, 'DD-MON-YYYY'), 'DAY')
FROM DATES
ORDER BY DATE;
结果是;
DATE TO_CHAR(D TO_CHAR(T
--------- --------- ---------
19-OCT-15 MONDAY SATURDAY
19-OCT-15 MONDAY SATURDAY
19-OCT-15 MONDAY SATURDAY
21-OCT-15 WEDNESDAY MONDAY
21-OCT-15 WEDNESDAY MONDAY
02-NOV-15 MONDAY SATURDAY
02-NOV-15 MONDAY SATURDAY
最佳答案
切勿在 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
。因为,您将 RR 格式转换为 YYYY 的值,该值已经是 DATE 。现在, 的第 27 天 0015 年 10 月 是 SUNDAY 。
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@!)))
了吗?过滤器怎么了?TO_DATE on SYSDATE 在内部被解释为
TO_DATE(TO_CHAR(SYSDATE@!))
。因此,首先应用 TO_CHAR ,其格式取决于您的本地 NLS_DATE_FORMAT ,然后转换回 DATE 。
更新 基于以下 OP 的评论...
用:
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
If you depend on the client's NLS settings, it might not work for a person who uses a different NLS in some different location.
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
不要反其道而行之。
关于sql - 为什么周二有时是周日?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33363871/