每当更新行时,我想用当前时间戳更新字段。
在MySQL中,我会在声明表时这样做
LastUpdate TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
但是“on update”部分不适用于SQLite。 我无法找到自动执行此操作的方法,是否需要声明触发器?
编辑:对于记录,这是我当前的触发器:
CREATE TRIGGER [UpdateLastTime]
AFTER UPDATE
ON Package
FOR EACH ROW
BEGIN
UPDATE Package SET LastUpdate = CURRENT_TIMESTAMP WHERE ActionId = old.ActionId;
END
由于
答案 0 :(得分:20)
是的,您需要使用触发器。 (只是检查:你发布的触发器是否正常工作?乍一看,它看起来很好。)
MySQL的ON UPDATE CURRENT_TIMESTAMP
是一个非常独特的单用途快捷方式。就是这样;对于任何其他值或TIMESTAMP
以外的任何列类型,此<> 不能类似地使用。 (请注意,TIMESTAMP
type page而不是CREATE TABLE
page是如何定义此功能的,因为此功能特定于TIMESTAMP
列,而不是CREATE TABLE
语句。)它也值得提及虽然它特定于TIMESTAMP
类型,SQLite doesn't even have distinct date/time types。
据我所知,没有其他RDBMS提供此快捷方式代替使用实际触发器。根据我的阅读,必须使用触发器在MS SQL,SQLite,PostgreSQL和Oracle上完成此操作。
路人的最后一句话:
不要将ON UPDATE
子句与外键约束相混淆。这是完全不同的东西,可能所有支持外键约束的RDBMS都有(包括MySQL和SQLite)。
答案 1 :(得分:3)
John对于默认的SQLite设置是正确的,此触发器会导致无限循环。要避免递归,请使用WHEN子句。
即使recursive_triggers
设置已开启,以下内容仍然有效:
PRAGMA recursive_triggers=1; --- test
CREATE TRIGGER [UpdateLastTime]
AFTER UPDATE
ON package
FOR EACH ROW
WHEN NEW.LastUpdate < OLD.LastUpdate --- this avoid infinite loop
BEGIN
UPDATE Package SET LastUpdate=CURRENT_TIMESTAMP WHERE ActionId=OLD.ActionId;
END;
答案 2 :(得分:0)
-- Describe UPDATELASTTIME
CREATE TRIGGER [UpdateLastTime]
AFTER
UPDATE
ON test
FOR EACH ROW
WHEN NEW.last_update_ts <= OLD.last_update_ts
BEGIN
update test set last_update_ts=CURRENT_TIMESTAMP where id=OLD.id;
END
-- Describe TEST
CREATE TABLE "main"."test" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"last_update_ts" DATETIME DEFAULT CURRENT_TIMESTAMP
);
答案 3 :(得分:0)
有更高效,更好,更干净的方法,例如:
-- List all required fields after 'OF' except the LastUpdate field to prevent infinite loop
CREATE TRIGGER UpdateLastTime UPDATE OF field1, field2, fieldN ON Package
BEGIN
UPDATE Package SET LastUpdate=CURRENT_TIMESTAMP WHERE ActionId=ActionId;
END;
像这样的代码已在我的项目中测试过。 深度sqlite触发器说明可以在https://www.sqlite.org/lang_createtrigger.html
找到