我正在创建一个使用 MySQL 作为数据库的身份验证服务器。 我正在使用一个表来存储刷新令牌,它看起来像这样:
CREATE TABLE IF NOT EXISTS REFRESH_TOKEN (
TOKEN VARCHAR(512) NOT NULL,
EXPIRATION DATETIME
) ENGINE=INNODB;
为了确保正确
DATETIME
,我使用以下触发器:
DROP TRIGGER IF EXISTS TG_RT_EXP;
DELIMITER //
CREATE TRIGGER TG_RT_EXP BEFORE INSERT ON REFRESH_TOKEN
FOR EACH ROW
BEGIN
SET NEW.EXPIRATION = FROM_UNIXTIME(NEW.EXPIRATION);
END;//
DELIMITER ;
为了测试两者,这里是使用的语句(从jwt.io提取的值)
INSERT INTO REFRESH_TOKEN
(TOKEN, EXPIRATION)
VALUES (
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
1796239022
);
发生 INSERT 后,ID 1265 的警告指出数据正在被截断,并且每个新行都有
1969-12-31 16:00:00
值而不是相应的转换。我删除了触发器,得到的值是 0000-00-00 00:00:00
,所以我猜测它与 INSERT 值格式有关。这与触发器、INSERT 值格式、列数据类型有关还是其他原因?
编辑:如果我尝试这样做
INSERT INTO REFRESH_TOKEN
(TOKEN, EXPIRATION)
VALUES (
'eyJhbGciOiJIUzI...',
FROM_UNIXTIME(1796239022)
);
值插入正确并且没有显示警告,为什么不能翻译成触发器?
您尝试将 BIGINT 值插入 DATETIME 列。
在执行任何触发操作之前,该值会转换为 DATETIME。此转换是根据日期和时间文字:
中描述的规则执行的采用 YYYYMMDDhhmmss 或 YYMMDDhhmmss 格式的数字,前提是该数字作为日期有意义。例如,19830905132800 和 830905132800 被解释为“1983-09-05 13:28:00”。
因此,提供的值
1796239022
被视为不正确的DATETIME值(它与上述任何格式都不匹配,因为它产生不正确的MONTH值96或23),并且转换结果为NULL,以确保您可以测试SELECT CAST(1796239022 AS DATETIME)
。当触发器触发时,为该列提供的值已转换为 NULL。