使用 TO_CHAR 将时间戳列转换为 char 时获得不同的年份

Getting different year when converting a timestamp column to char using TO_CHAR

这是来自 Oracle 12C,我什至尝试过在线 Oracle 编译器

谁能解释一下为什么会这样 以下是我遵循的简单步骤

-- 创建了一个 GTT。物理 table 也有问题

创建全局临时文件 table GTT_A ( b 时间戳(3));

-- 插入了 1901 年的日期

插入 GTT_A 值 ('01-JAN-1901');

-- 检索时,直接列给出的年份为 19,当转换为 char 时,它给出的是 2019。对此有某种解释吗

Select b, to_char(b,'mm-dd-yyyy') 来自 GTT_A;

使用

检查您的 NLS_TIMESTAMP_FORMAT
SELECT
  value
FROM
  V$NLS_PARAMETERS
WHERE
  parameter = 'NLS_TIMESTAMP_FORMAT';

并在插入之前使用以下命令将年份更改为四位数

     alter session set nls_timestamp_format='DD-MON-YYYY HH.MI.SSXFF AM'

'01-JAN-1901'不是时间戳,是字符串。

不要插入字符串;使用日期文字(它将被转换为时间戳):

Insert into GTT_A values (DATE '1901-01-01');

或者时间戳文字,如果你想包含时间部分:

Insert into GTT_A values (TIMESTAMP '1901-01-01 00:00:00');

或者,如果您想使用字符串,则将 TO_DATE 与格式模型一起使用,以将字符串显式转换为日期:

Insert into GTT_A values (
  TO_DATE(
    '01-JAN-1901',
    'DD-MON-YYYY',
    'NLS_DATE_LANGUAGE=AMERICAN'
  )
);

TO_TIMESTAMP:

Insert into GTT_A values (
  TO_TIMESTAMP(
    '01-JAN-1901',
    'DD-MON-YYYY',
    'NLS_DATE_LANGUAGE=AMERICAN'
  )
);

如果您依赖隐式转换,那么 Oracle 将尝试将您的字符串隐式转换为日期和您的查询:

Insert into GTT_A values ('01-JAN-1901');

有效转换为:

Insert into GTT_A values (
  TO_TIMESTAMP(
    '01-JAN-1901',
    ( SELECT value
      FROM   NLS_SESSION_PARAMETERS
      WHERE  parameter = 'NLS_TIMESTAMP_FORMAT' )
  )
);

每个用户都可以在 任何 时间设置他们自己的会话参数,这样您的查询可以工作一分钟,然后用户更新他们的会话参数并且您的查询停止工作而无需更改您的询问。不要依赖隐式转换;这样你就不需要使用 date/timestamp 文字或使用显式转换来转换任何东西。