在使用SQLite更新current_timestamp

时间:2011-07-05 05:57:33

标签: sqlite triggers

每当更新行时,我想用当前时间戳更新字段。

在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

由于

4 个答案:

答案 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

找到