Последствия изменения 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_FORMAT и NLS_TIMESTAMP_FORMAT не особенно полезны, поскольку они всегда переопределяются настройками клиента. Таким образом, даже если вы измените настройку базы данных, 99%% времени, когда пользователь приходит и подключается к базе данных, их сеанс будет устанавливать NLS_DATE_FORMAT и NLS_TIMESTAMP_FORMAT на основе NLS_LANG клиента или других национальных языковых настроек (например, приложения, использующие тонкий драйвер JDBC использует параметры интернационализации JVM, а не полагается на клиента NLS_LANG) и отменяет настройки, которые вы сделали в базе данных. Есть несколько угловых случаев, связанных с заданиями базы данных, с использованием DBMS_JOBS или DBMS_SCHEDULER, где нет клиента, где используются базы данных NLS_DATE_FORMAT и NLS_TIMESTAMP_FORMAT, но это довольно редко.

Вы можете создать триггер входа, который сделал ALTER SESSION, чтобы установить NLS_DATE_FORMAT и NLS_TIMESTAMP_FORMAT для ваших сеансов. Это приведет к отмене настроек, запрошенных клиентом при создании сеанса. Как указывает Ник, вам придется беспокоиться о том, что другие запросы полагаются на текущую настройку для неявных преобразований, и ваше изменение может нарушить этот код.

В общем, вам гораздо лучше избегать неявных преобразований, где это возможно, но особенно, когда речь заходит о преобразовании строк в даты или из дат и временных меток только потому, что существует множество разных форматов, которые вы настраиваете на проблемы. Если вы хотите, чтобы указать дату буквального в вашем коде, вы гораздо лучше, используя дату 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_DATE или TO_TIMESTAMP с явной формой маски.


0

Существующие запросы, которые полагаются на этот формат, могут возвращать разные результаты.

Проверьте, что ваш существующий код интерпретирует поля TIMESTAMP способом, зависящим от формата, и обязательно обновите его, если это произойдет. Также обратите внимание, что NLS_TIMESTAMP_FORMAT может быть установлен на уровне базы данных или клиента, поэтому обратите внимание на формат, который видит клиент, когда он выполняет код.