我们有一个表定义为:
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
会话参数如下:
1条答案
按热度按时间w1jd8yoj1#
insertedOn TIMESTAMP
定义为不包含时区的TIMESTAMP
。然而,函数CURRENT_TIMESTAMP
返回一个不同的数据类型,一个 * 确实 * 包括时区(TIMESTAMP WITH TIME ZONE
)的数据类型。为了将此数据类型插入到TIMESTAMP
列中,Oracle必须根据您的时区设置进行转换,这就是转换发生的地方。若要修复,请重新定义列:
PL/SQL变量也是如此。任何时候你在变量或表列中存储
SYSTIMESTAMP
或CURRENT_TIMESTAMP
的结果时,请确保类型为TIMESTAMP WITH TIME ZONE
,否则它将根据你的时区设置进行转换和可能的偏移,这可能会导致一些不需要的结果。