Oracle current_timestamp在同一会话中提供不同的值

ttygqcqt  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(117)

我们有一个表定义为:

CREATE TABLE tokens (
  token VARCHAR2(36) NOT NULL PRIMARY KEY,
  username VARCHAR2(60) NOT NULL,
  insertedOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

如果我们使用SQL Developer连接到数据库,则会有以下内容:

SELECT CURRENT_TIMESTAMP FROM DUAL
-- 25-AGO-23 17:15:01,515019000 EUROPE/BERLIN

SELECT SESSIONTIMEZONE FROM DUAL;
-- EUROPE/BERLIN

但是,如果我们在同一个会话期间从SQL Developer插入一行:

INSERT INTO tokens (token, username) VALUES ('123', 'john');

该行插入了一个意外的时间戳(-1小时):

SELECT * FROM tokens;
-- 123 john 16:15:27,929125000

为什么时间戳插入了不同的值?
数据库为Oracle Database 10 g Enterprise Edition 10.2.0.4.0
会话参数如下:

w1jd8yoj

w1jd8yoj1#

insertedOn TIMESTAMP定义为不包含时区的TIMESTAMP。然而,函数CURRENT_TIMESTAMP返回一个不同的数据类型,一个 * 确实 * 包括时区(TIMESTAMP WITH TIME ZONE)的数据类型。为了将此数据类型插入到TIMESTAMP列中,Oracle必须根据您的时区设置进行转换,这就是转换发生的地方。
若要修复,请重新定义列:

CREATE TABLE tokens (
  token VARCHAR2(36) NOT NULL PRIMARY KEY,
  username VARCHAR2(60) NOT NULL,
  insertedOn TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

PL/SQL变量也是如此。任何时候你在变量或表列中存储SYSTIMESTAMPCURRENT_TIMESTAMP的结果时,请确保类型为TIMESTAMP WITH TIME ZONE,否则它将根据你的时区设置进行转换和可能的偏移,这可能会导致一些不需要的结果。

相关问题