Специальный формат временной метки Oracle «DD-MON-RR HH.MI.SSXFF AM»

У меня проблема с форматом временной метки Oracle 11g.

Вот что у меня есть: select to_timestamp('21-OCT-15 08.24.30.000000000 PM','DD-MON-RR HH.MI.SSXFF AM') from dual;

Ответ из базы данных: ORA-01855: AM/A.M. or PM/P.M. required 01855. 00000 - "AM/A.M. or PM/P.M. required"

Я также пытался изменить настройки сеанса с помощью нескольких команд и до сих пор ничего.

alter session set NLS_LANGUAGE='ENGLISH';
alter session set NLS_DATE_LANGUAGE='ENGLISH';
alter session set NLS_TIMESTAMP_FORMAT = 'DD-MON-RR HH.MI.SSXFF AM';
alter session set NLS_TIMESTAMP_TZ_FORMAT='DD-MON-RR HH.MI.SSXFF AM';

Я не могу изменить формат метки времени в операторе SELECT, нужно оставить как есть. Я предполагаю, что проблема в настройках сеанса.

Кто-то опытный в администрировании баз данных оракула может что-то подсказать, я попробую. Я знаю, что есть пара похожих сообщений, но я не нашел решения. Спасибо

Вот мои настройки сеанса.

select * from nls_session_parameters;

Параметры сеанса


person Josip    schedule 21.11.2015    source источник
comment
Возможно, проблема в том, что вы используете период . в качестве разделителя для компонентов времени и в качестве (по умолчанию) символа счисления. Это работает с 'DD-MON-RR HH.MI.SSXFF9 AM'? NLS_LANGUAGE устанавливает язык сообщений об ошибках, я предполагаю, что вы имеете в виду NLS_DATE_LANGUAGE.   -  person Wernfried Domscheit    schedule 21.11.2015
comment
@WernfriedDomscheit Я также пытался изменить NLS_DATE_LANGUAGE, но проблема осталась. Также с вашим предложением изменить NLS_TIMESTAMP_FORMAT не работает.   -  person Josip    schedule 21.11.2015
comment
Вы можете запустить select * from nls_session_parameters; и вставить отформатированный результат в вопрос? У меня на 12с работает нормально. Как только вы предоставите детали, мы сравним разницу.   -  person Utsav    schedule 21.11.2015
comment
@Utsav Я добавил в исходный пост картинку с результатами.   -  person Josip    schedule 21.11.2015


Ответы (4)


Основная проблема заключается в том, что на уровне сеанса у вас есть nls_numeric_characters=',.', а ваша строка временной метки вместо этого содержит точку (.) в качестве разделителя секунд из микросекунд.

Функция to_timestamp() может принимать третий параметр для переопределения настроек NLS. Вот вам небольшая демонстрация...

Connected to Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 
Connected as ******@******

--- This is how it behaves in your database (with "," as the decimals separator) ...

SQL> alter session set nls_numeric_characters = ',.';

Session altered

SQL> select to_timestamp('21-OCT-15 08.24.30.000000000 PM','DD-MON-RR HH.MI.SSXFF AM') as xx from dual;

select to_timestamp('21-OCT-15 08.24.30.000000000 PM','DD-MON-RR HH.MI.SSXFF AM') as xx from dual

ORA-01855: AM/A.M. or PM/P.M. required

--- This is how it behaves in my database (with "." as the decimals separator) ...

SQL> alter session set nls_numeric_characters = '. ';

Session altered

SQL> select to_timestamp('21-OCT-15 08.24.30.000000000 PM','DD-MON-RR HH.MI.SSXFF AM') as xx from dual;

XX
-------------------------------------------------
21.10.15 20:24:30.000000000

--- Now back to your database settings and let's make the conversion NLS-settings-indepenent ...

SQL> alter session set nls_numeric_characters = ',.';

Session altered

SQL> select to_timestamp('21-OCT-15 08.24.30.000000000 PM','DD-MON-RR HH.MI.SSXFF AM', 'nls_numeric_characters = ''. ''') as xx from dual;

XX
-------------------------------------------------
21.10.15 20:24:30,000000000

SQL> 

Обратите внимание на третий параметр функции to_timestamp() в третьем SELECT. Это то, что вы могли бы сделать, кроме всех других правильных ответов.

person peter.hrasko.sk    schedule 25.11.2015

Создайте резервную копию настроек NLS и запустите их.

    ALTER SESSION SET NLS_DATE_FORMAT='DD-MON-RRRR HH24:MI:SS';
    ALTER SESSION SET NLS_DATE_LANGUAGE='AMERICAN';
    ALTER SESSION SET NLS_TIME_FORMAT='HH.MI.SSXFF AM';
    ALTER SESSION SET NLS_TIMESTAMP_FORMAT='DD-MON-RR HH.MI.SSXFF AM';
    ALTER SESSION SET NLS_TIME_TZ_FORMAT='HH.MI.SSXFF AM TZR';
    ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='DD-MON-RRRR HH.MI.SSXFF AM TZR';

Затем снова запустите оператор SQL.

person Utsav    schedule 21.11.2015

Наконец, я добавил Territory в предыдущий список измененных свойств сеанса, чтобы он работал на меня. Спасибо

ALTER SESSION SET NLS_TERRITORY=AMERICA;
ALTER SESSION SET NLS_DATE_LANGUAGE='AMERICAN';
ALTER SESSION SET NLS_TIME_FORMAT='HH.MI.SSXFF AM';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT='DD-MON-RR HH.MI.SSXFF AM';
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='DD-MON-RRRR HH.MI.SSXFF AM TZR';
ALTER SESSION SET NLS_TIME_TZ_FORMAT='HH.MI.SSXFF AM TZR';
person Josip    schedule 25.11.2015
comment
В моем случае предыдущие ответы не сработали, этот день спасает. - person pburgr; 13.05.2019

Попробуйте следующее: SELECT TO_CHAR(TO_TIMESTAMP(**'2015-11-21-13:03:07.04776'**),'DD-MON-RR HH.MI.SSXFF AM') FROM DUAL;Формат метки времени между кавычками должен быть таким же, как результат этого запроса: SELECT TO_CHAR(LOCALTIMESTAMP) FROM DUAL

person Nik    schedule 21.11.2015