Oracle NLS_TERRITORY переопределяет NLS_DATE_FORMAT - PullRequest
0 голосов
/ 07 февраля 2020

Когда в приложении PHP я указываю

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_DATE_LANGUAGE = 'RUSSIAN';

формат выходных данных соответствует ожидаемому 2020-01-31 21:21:47 Но когда я добавляю

ALTER SESSION SET NLS_TERRITORY = 'CIS';

NLS_DATE_FORMAT не вступает в силу, NLS_TERRITORY переопределяет его. 31.01.20

Ответы [ 3 ]

2 голосов
/ 07 февраля 2020

Oracle формат даты по умолчанию зависит от настройки NLS_TERRITORY. Поэтому, когда вы устанавливаете NLS_TERRITORY, вы также говорите Oracle, чтобы сбросить NLS_DATE_FORMAT (и другие подобные параметры) на значения по умолчанию для новой территории.

Из документации Oracle :

1.206 NLS_TERRITORY

NLS_TERRITORY указывает название территории, правила которой должны соблюдаться для нумерации дня и недели.

.. .

Этот параметр также устанавливает формат даты по умолчанию, десятичный символ по умолчанию и разделитель групп, а также символы ISO и местной валюты по умолчанию.

Для получения информации об этих настройках см. " NLS_DATE_FORMAT "," NLS_NUMERIC_CHARACTERS "," NLS_CURRENCY "и" NLS_ISO_CURRENCY ".

Если вы хотите изменить территорию и язык и формат даты, вам нужно сначала изменить территорию (что неявно изменит значения для NLS_DATE_FORMAT, et c. На по умолчанию территории), а затем вы можете изменить язык и формат даты, чтобы переопределить эти настройки территории по умолчанию:

Итак:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_DATE_LANGUAGE = 'RUSSIAN';
ALTER SESSION SET NLS_TERRITORY = 'CIS';

должно быть:

ALTER SESSION SET NLS_TERRITORY = 'CIS';
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_DATE_LANGUAGE = 'RUSSIAN';
1 голос
/ 08 февраля 2020

В дополнение к другим ответам вы должны объединить настройки в один оператор ALTER SESSION:

ALTER SESSION SET NLS_TERRITORY = 'CIS' NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_DATE_LANGUAGE = 'RUSSIAN';

Это особенно рекомендуется, если вы выполняете оператор из PHP (а не только с помощью блока PL / SQL или триггера входа в систему), поскольку это уменьшает количество циклов между PHP и базой данных и может иметь значительное преимущество в производительности.

Для обсуждения использования триггеров см. p 304 бесплатных Oracle PDF Метрополитен PHP и Oracle Ручной .

Если вам нужно выполнить инструкцию из PHP, а другие SQL команды, которые выполняются при входе в систему, оберните их все в анонимный блок PL / SQL:

begin
     execute immediate
       'alter session set nls_date_format = ''YYYY-MM-DD'' nls_language = AMERICAN';
     -- other SQL statements could be put here
end;

Это может быть выполнено с одним вызовом oci_parse(), поэтому для него требуется только одно обращение.

1 голос
/ 07 февраля 2020

nls_date_format (среди прочих настроек) является производным от nls_territory. Поэтому, когда вы устанавливаете территорию, база данных также устанавливает формат даты по умолчанию для этой области:

select value from nls_session_parameters
where  parameter = 'NLS_DATE_FORMAT';

VALUE
--------------------------------------------------------------------------------
DD-MON-RR

ALTER SESSION SET NLS_TERRITORY = 'CIS';

select value from nls_session_parameters
where  parameter = 'NLS_DATE_FORMAT';

VALUE
--------------------------------------------------------------------------------
DD.MM.RR

Поэтому вам необходимо установить формат даты после территории:

ALTER SESSION SET NLS_TERRITORY = 'CIS';
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_DATE_LANGUAGE = 'RUSSIAN';
select value from nls_session_parameters
where  parameter = 'NLS_DATE_FORMAT';

VALUE
--------------------------------------------------------------------------------
YYYY-MM-DD HH24:MI:SS

Или - еще лучше - используйте явную маску формата в ваших конверсиях:

ALTER SESSION SET NLS_TERRITORY = 'CIS';
select sysdate, to_char ( sysdate, 'YYYY-MM-DD HH24:MI:SS' ) from dual;

SYSDATE  TO_CHAR(SYSDATE,'YY
-------- -------------------
07.02.20 2020-02-07 09:25:35
...