【问题标题】:How to produce the same result of to_char() on the same DB instance, but from different sessions?如何在同一个数据库实例上产生相同的 to_char() 结果,但来自不同的会话?
【发布时间】:2013-05-05 10:25:56
【问题描述】:

我有一个小实用函数,可以从给定日期计算星期几:

select to_number(to_char(to_date('20130330', 'YYYYMMDD'),'D')) from dual;

在同一个数据库实例上执行此语句,但在两台不同的机器上会产生两种不同的结果!

问题是:如何修改代码以在两台不同的PC上但使用相同的数据库实例得到相同的结果?

详情

当我使用这些 nls_session 参数从我的电脑启动会话时,结果为 6:

select * from nls_session_parameters;

NLS_LANGUAGE    HUNGARIAN
NLS_TERRITORY   HUNGARY
NLS_CURRENCY    Ft
NLS_ISO_CURRENCY    HUNGARY
NLS_NUMERIC_CHARACTERS  , 
NLS_CALENDAR    GREGORIAN
NLS_DATE_FORMAT RR-MON-DD
NLS_DATE_LANGUAGE   HUNGARIAN
NLS_SORT    HUNGARIAN
NLS_TIME_FORMAT HH24.MI.SSXFF
NLS_TIMESTAMP_FORMAT    RR-MON-DD HH24.MI.SSXFF
NLS_TIME_TZ_FORMAT  HH24.MI.SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT RR-MON-DD HH24.MI.SSXFF TZR
NLS_DUAL_CURRENCY   Ft
NLS_COMP    BINARY
NLS_LENGTH_SEMANTICS    BYTE
NLS_NCHAR_CONV_EXCP FALSE

相同的数据库实例给出不同的结果:7通过从具有这些会话参数的不同电脑启动会话:

PARAMETER    VALUE
NLS_LANGUAGE    AMERICAN
NLS_TERRITORY    AMERICA
NLS_CURRENCY    $
NLS_ISO_CURRENCY    AMERICA
NLS_NUMERIC_CHARACTERS    .,
NLS_CALENDAR    GREGORIAN
NLS_DATE_FORMAT    DD-MON-RR
NLS_DATE_LANGUAGE    AMERICAN
NLS_SORT    BINARY
NLS_TIME_FORMAT    HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT    DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT    HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT    DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY    $
NLS_COMP    BINARY
NLS_LENGTH_SEMANTICS    BYTE
NLS_NCHAR_CONV_EXCP    FALSE

对我来说正确的结果是 7,但它必须在我的电脑上提供。我尝试了以下方法但没有成功:

  • 将 NLS_LANGUAGE 更改为 AMERICAN
  • 使用 to_char() 和可选的 nls_language 参数

有什么建议吗?

【问题讨论】:

    标签: oracle oracle11g to-char nls-lang


    【解决方案1】:

    星期几的操作设置是NLS_TERRITORY。

    【讨论】:

      【解决方案2】:

      如果您可以发出alter session,那么 NLS_TERRITORY 可能是要走的路,正如@JoachimIsaksson 所说。但如果你不能,那么不幸的是TO_CHAR() 不支持通过其可选的nlsparms 参数即时修改它。

      您可以将其作为最后的手段进行暴力破解,例如在匈牙利会议上:

      alter session set nls_language = 'HUNGARIAN';
      
      select to_char(to_date('20130330', 'YYYYMMDD'), 'DY') as hungarian,
          to_char(to_date('20130330', 'YYYYMMDD'),
              'DY', 'NLS_DATE_LANGUAGE=AMERICAN') as american
      from dual;
      
      HUN AME
      --- ---
      SZO SAT
      
      select case to_char(to_date('20130330', 'YYYYMMDD'),
          'DY', 'NLS_DATE_LANGUAGE=AMERICAN')
              when 'SUN' then 1 when 'MON' then 2 when 'TUE' then 3
              when 'WED' then 4 when 'THU' then 5 when 'FRI' then 6
              when 'SAT' then 7
          end as american
      from dual;
      
        AMERICAN
      ----------
               7
      

      ... 这很丑陋,但避免了更改会话的任何副作用。当然,如果这将成为多个地方的问题,您可以将其变成一个函数。

      【讨论】:

        【解决方案3】:

        对于国际惯例,只需使用 trunc(date)-trunc(date,'IW')+1 如果您更喜欢美国惯例,则为 trunc(date+1)-trunc(date+1,'IW')+1。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-25
          • 1970-01-01
          • 2019-02-03
          • 2017-01-23
          相关资源
          最近更新 更多