更改NLS_TIMESTAMP_FORMAT的后果


4

我管理一个9.2.0.8数据库,其中NLS_TIMESTAMP_FORMAT设置为'DD-MON-RR HH.MI.SSXFF AM';

此使用CAST TO TIMESTAMP功能时,会导致奇怪的结果:

select CAST('14-SEP-2011' AS TIMESTAMP) "DATE" from dual; 
---------- 
14-SEP-2020 11:00:00.000000 AM 

如果我改变NLS_TIMESTAMP_FORMAT'DD-MON-YYYY HH.MI.SSXFF AM'话,我好去。

会将数据库中的NLS_TIMESTAMP_FORMAT参数更改为YYYY会产生什么后果?

4

数据库级别NLS_DATE_FORMATNLS_TIMESTAMP_FORMAT参数不是特别有用,因为它们总是被客户端设置覆盖。因此,即使您更改了数据库设置,用户出现并连接到数据库时的时间为99 +%,他们的会话将根据客户端的NLS_LANG或其他本地语言设置(即使用的应用程序)设置NLS_DATE_FORMATNLS_TIMESTAMP_FORMAT瘦JDBC驱动程序使用JVM的国际化设置,而不是依赖于客户端NLS_LANG)并推翻您在数据库中所做的设置。有几个角落案例涉及使用DBMS_JOBSDBMS_SCHEDULER的数据库作业,其中没有使用数据库NLS_DATE_FORMATNLS_TIMESTAMP_FORMAT的客户端,但我相信这些数据库作业非常少见。

您可以创建一个登录触发器,它执行ALTER SESSION来为您的会话设置NLS_DATE_FORMATNLS_TIMESTAMP_FORMAT。这将推翻客户在创建会话时所请求的设置。正如Nick指出的那样,您不得不担心其他查询依赖于隐式转换的当前设置,您的更改可能会破坏该代码。

一般来说,只要可能,避免隐式转换,特别是在将字符串转换为日期和时间戳时,避免隐式转换要简单得多,因为存在太多不同的格式以致于无法自行设置问题。如果你想指定代码文本的日期,你更好的使用ANSI日期和时间戳语法

SQL> ed 
Wrote file afiedt.buf 

    1 select cast(date '2011-09-14' as timestamp) dt, 
    2   timestamp '2011-09-14 13:15:30' ts 
    3* from dual 
SQL>/

DT        TS 
------------------------------ ----------------------------------- 
14-SEP-11 12.00.00.000000 AM 14-SEP-11 01.15.30.000000000 PM 

如果你想将字符串转换为日期或时间戳记,你最好使用带有明确格式掩码的TO_DATETO_TIMESTAMP


0

依赖于此格式的现有查询可能会返回不同的结果。

检查您的现有代码是否以格式相关的方式解释TIMESTAMP字段,并确保在其中更新它。还要注意NLS_TIMESTAMP_FORMAT可以设置在数据库或客户端级别,因此请注意客户端在执行代码时看到的格式。