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;
Run Code Online (Sandbox Code Playgroud)
结果是;
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
Run Code Online (Sandbox Code Playgroud)
Lal*_*r B 10
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
Run Code Online (Sandbox Code Playgroud)
根本原因
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
Run Code Online (Sandbox Code Playgroud)
所以今年改为0015.因为,您已将RR格式转换为YYYY,以获取已经是DATE的值.
现在,27天的0015十月是个星期天.
SQL> select to_char(to_date('27-OCT-0015','DD-MON-YYYY'),'DAY') FROM DUAL;
TO_CHAR(T
---------
SUNDAY
Run Code Online (Sandbox Code Playgroud)
要了解内部行为,让我们看一个小型演示:
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@!)))
Run Code Online (Sandbox Code Playgroud)
你看到的filter(SYSDATE@!=TO_DATE(TO_CHAR(SYSDATE@!))).过滤器发生了什么?
SYSDATE上的TO_DATE在内部被解释为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
如果您依赖于客户端的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
Run Code Online (Sandbox Code Playgroud)
反之亦然.
由于sysdate这个表达式已经是一个日期:
to_date(sysdate, 'DD-MON-YYYY')
Run Code Online (Sandbox Code Playgroud)
......既冗余又脆弱.您要求Oracle使用任何值将日期转换为字符串NLS_DATE_FORMAT,NLS_TERRITORY并且NLS_LANGUAGE当前使用固定(可能不同)格式将其解析为日期.垃圾进垃圾出.
一些提示:
我也不太喜欢使用月份名称作为交换格式; 我认为数字不容易出错.
| 归档时间: |
|
| 查看次数: |
371 次 |
| 最近记录: |