0

当我在 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 覆盖它。20 年 1 月 31 日

4

3 回答 3

2

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
于 2020-02-07T09:26:03.257 回答
2

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等的值更改为地区的默认值),然后您可以将日期语言和格式更改为覆盖那些默认区域设置:

所以:

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';
于 2020-02-07T09:40:21.263 回答
1

除了其他答案,您应该将设置组合成一个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 和数据库之间的往返次数,并且可以显着提高性能。

有关使用触发器的讨论,请参阅免费的 Oracle PDF The Underground PHP and Oracle Manual 的第 304 页。

如果确实需要从 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()调用执行,因此只需要一次往返。

于 2020-02-07T22:08:36.637 回答