4

当我在桌面上运行以下查询时

Select to_char(join_date, 'DD-MON-YYYY')
From students
group by to_char(join_date, 'DD-MON-YYYY');

我得到以下输出:

23-Oct-2012
25-Oct-2012
23-Oct-2012
23-Oct-2012
23-Oct-2012
26-Oct-2012
23-Oct-2012
24-Oct-2012
23-Oct-2012

但是如果我在不同的服务器上运行它,输出结果如下:

23-Oct. -2012
25-Oct. -2012
23-Oct. -2012
23-Oct. -2012
23-Oct. -2012
26-Oct. -2012
23-Oct. -2012
24-Oct. -2012
23-Oct. -2012

有什么想法可能导致这种情况吗?第二台服务器与我在不同的国家/地区运行,因此其区域设置可能不同。

更新:

NLS_DATE_FORMAT 在两台服务器上都是 DD-Mon-RRRR。

4

3 回答 3

1

当 oracle 从数据库中检索日期字段并将其显示给您时,会进行隐式强制转换。此转换的格式模式在 oracle 配置中设置。引用 oracle 文档

Oracle 日期值的默认日期格式源自 NLS_DATE_FORMAT 和 NLS_DATE_LANGUAGE 初始化参数

如果 NLS_DATE_FORMAT 在两台服务器上都是 DD-Mon-RRRR,请检查 NLS_DATE_LANGUAGE

于 2012-10-29T19:05:36.777 回答
1

正如 danihp 所暗示的,差异可能取决于NLS_LANGUAGE设置,这可能源自更高的 NLS 参数。您可以覆盖它以获得一致的结果 - 尽管这不一定是一个好主意 - 如全球化支持指南中所述。运行这些查询应该在两台服务器上产生一致的结果(根据您显示的数据猜测您的其中一台是法语):

select to_char(join_date, 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=FRENCH')
from students ...;

select to_char(join_date, 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH')
from students ...;

混乱的背后可能是您期望MON代表的内容。如SQL 参考中所述,MON是“月份的缩写名称”;这意味着它不一定是三个字符的缩写。如何缩写完整的月份名称取决于 NLS 设置。

在英语中,所有月份名称都可以明确地缩写为三个字符:

select level as l,
    to_char(to_date(level, 'MM'), 'Month', 'NLS_DATE_LANGUAGE=ENGLISH'),
    to_char(to_date(level, 'MM'), 'Mon', 'NLS_DATE_LANGUAGE=ENGLISH')
from dual
connect by level <= 12
order by 1

         L TO_CHAR(TO_DATE(LEVEL,'MM'),'MONTH', TO_CHAR(TO_D
---------- ------------------------------------ ------------
         1 January                              Jan
         2 February                             Feb
         3 March                                Mar
         4 April                                Apr
         5 May                                  May
         6 June                                 Jun
         7 July                                 Jul
         8 August                               Aug
         9 September                            Sep
        10 October                              Oct
        11 November                             Nov
        12 December                             Dec

在法语中,情况并非如此:

select level as l,
    to_char(to_date(level, 'MM'), 'Month', 'NLS_DATE_LANGUAGE=FRENCH'),
    to_char(to_date(level, 'MM'), 'Mon', 'NLS_DATE_LANGUAGE=FRENCH')
from dual
connect by level <= 12
order by 1;

         L TO_CHAR(TO_DATE(LEVEL,'MM'),'MONTH', TO_CHAR(TO_DATE(LEVE
---------- ------------------------------------ --------------------
         1 Janvier                              Janv.
         2 Février                              Févr.
         3 Mars                                 Mars
         4 Avril                                Avr.
         5 Mai                                  Mai
         6 Juin                                 Juin
         7 Juillet                              Juil.
         8 Août                                 Ao
         9 Septembre                            Sept.
        10 Octobre                              Oct.
        11 Novembre                             Nov.
        12 Décembre                             Déc.

显然,使用三个字母的缩写会给 Juin 和 Juillet 带来困难。据推测,用句号表示缩写是一种文化现象,有些月份需要四个字符才能区分,这会将MON格式长度增加到五个字符。

格式模型将其保持为固定宽度可能有点令人惊讶,因此您在中间有一个空间用于较短的缩写,就像在您的原始数据中一样。我敢肯定,无论哪种方式都可以争论,而且似乎始终如一地应用。我不知道有任何方法可以自动停止。

于 2012-10-30T23:00:09.993 回答
1

您没有将代码错误输入为:

select to_char(join_date,'dd-mon.-yyyy') from students;

这将给出结果:

23-Oct.-2012
于 2012-10-29T23:06:25.503 回答