首页 > 大数据 > 正文

使用Oracle数据库中PL/SQL的函数时需注意的问题

2012-10-23 14:46:20  来源:TechTarget中国

摘要:在使用Oracle数据库中PL/SQL的to_date 和 to_char函数时需要注意哪些问题,专家Dan Clamage给出了一些提示。
关键词: Oracle PL/

    问:在使用PL/SQL中to_date和to_char函数时我有几点疑惑,请看具体例子:


    SELECT TO_CHAR(TO_DATE(TO_CHAR(TO_DATE(‘23-MAY-2001','DD-MON-YYYY’),‘DD-MON-YY’),‘DD-MON-YY’),‘DD-MON-YYYY’) FROM DUAL;


    返回值是23-MAY-2001


    然后我做了些修改


    SELECT TO_CHAR(TO_DATE(TO_CHAR(TO_DATE(‘23-MAY-1901','DD-MON-YYYY’),‘DD-MON-YY’),‘DD-MON-YY’),‘DD-MON-YYYY’) FROM DUAL;


    但是返回值依然是:23-MAY-2001


    于是我把格式改为RR:


    SELECT TO_CHAR(TO_DATE(TO_CHAR(TO_DATE(‘23-MAY-1901','DD-MON-RRRR’),‘DD-MON-RR’),‘DD-MON-RR’),‘DD-MON-RRRR’) FROM DUAL;


    返回值还是:23-MAY-2001


    请问其中的原因是什么?


    答:针对第一条语句,“23-MAY-2001”是一个字符串。它看起来像是一个日期,但实际上不是,请不要将日期字符串和DATE数据类型混淆。那现在让我们来分别看一下PL/SQL的to_date 和 to_char表达式,从里向外来一一解读。针对第一个表达式,我们先看:


    select TO_DATE(‘23-MAY-2001','DD-MON-YYYY’) from dual;


    它会返回一个DATE值:05/23/2001,其中年份是完整的。然后再来看这一条:


    select TO_CHAR(TO_DATE(‘23-MAY-2001','DD-MON-YYYY’),‘DD-MON-YY’) from dual;


    它将返回一个字符串:23-MAY-01,那么这个01指的是1901还是2001呢?实际上哪一个都不是,它是一个STRING值而不是DATE值。继续看下一个:


    select TO_DATE(TO_CHAR(TO_DATE(‘23-MAY-2001','DD-MON-YYYY’),‘DD-MON-YY’),‘DD-MON-YY’) from dual;


    它返回的是DATE:05/23/2001,其中YY假定的就是当前的世纪。[page]
    现在让我们来看看第二条表达式:


    SELECT TO_CHAR(TO_DATE(TO_CHAR(TO_DATE(‘23-MAY-1901','DD-MON-YYYY’),‘DD-MON-YY’),‘DD-MON-YY’),‘DD-MON-YYYY’) FROM DUAL;


    我们不需要拆开来看到底如何从DATE转换为STRING又在转换为DATE,让我们来仔细看看你更改的RR格式对结果的影响:


    SELECT TO_CHAR(TO_DATE(TO_CHAR(TO_DATE(‘23-MAY-1901','DD-MON-RRRR’),‘DD-MON-RR’),‘DD-MON-RR’),‘DD-MON-RRRR’) FROM DUAL;


    首先是:


    select TO_DATE(‘23-MAY-1901','DD-MON-RRRR’) from dual;


    它返回的是DATE值:05/23/1901,如我们所料。然后:


    select TO_CHAR(TO_DATE(‘23-MAY-1901','DD-MON-RRRR’),‘DD-MON-RR’) from dual;


    它返回一个字符串:23-MAY-01,因为在输出时使用的是RR而不是RRRR.所以,你无法判断到底是哪个世纪。最后:


    select TO_DATE(TO_CHAR(TO_DATE(‘23-MAY-1901','DD-MON-RRRR’),‘DD-MON-RR’),‘DD-MON-RR’) from dual;


    它返回的是DATE值:05/23/2001,RR格式有所谓的“开窗口”习惯。关于这个问题你可以参考Oracle官方文档,但是基本上可以说,如果指定的两位数年份在00-49之间(本例就是),而且当时年份最后两位也在00-49之间(12即在此范围)时。那么它返回年份的头两位数将会和当时年费的头两位保持一致。


    这就是你所提到的问题根源所在。因为2001的后两位是在00-49的范围内,而2012的后两位也在范围内,所以返回的值永远是2001.


    因此在使用PL/SQL的to_date 和 to_char函数时需要注意以下几点:


    ●要使用明确的DATE转换程序;绝不要让表达式有任何含糊不清的地方。


    ●显示完整年份的时候尽量使用YYYY日期格式。


    ●当遇到不确定情况时,在参考官方文档的同时也要自己实际动手实验几次。事实上,官方文档并不是100%准确,有些时候还会出现模糊的概念。如果一味按照文档来定,也许会造成更多的误解和问题。


    ●最后,使用RR的时候要分清2050和2049之间的区别。不要你写的代码到时只有你能看懂,要尽量清楚明了,否则别人要用的时候容易造成不必要的麻烦。
 


第三十八届CIO班招生
国际CIO认证培训
首席数据官(CDO)认证培训
责编:zhangyexi

免责声明:本网站(http://www.ciotimes.com/)内容主要来自原创、合作媒体供稿和第三方投稿,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证有关资料的准确性及可靠性,读者在使用前请进一步核实,并对任何自主决定的行为负责。本网站对有关资料所引致的错误、不确或遗漏,概不负任何法律责任。
本网站刊载的所有内容(包括但不仅限文字、图片、LOGO、音频、视频、软件、程序等)版权归原作者所有。任何单位或个人认为本网站中的内容可能涉嫌侵犯其知识产权或存在不实内容时,请及时通知本站,予以删除。