sqlite触发器会触发其他触发器吗?

时间:2014-01-19 22:21:14

标签: sqlite triggers timestamp sql-update

我正在尝试在sqlite中实现等效的“ON UPDATE CURRENT_TIMESTAMP”MySQL功能。 我的想法是使用这样的触发器:

CREATE TRIGGER last_update_trigger
AFTER UPDATE
ON mytable
FOR EACH ROW
BEGIN
UPDATE mytable SET last_update = CURRENT_TIMESTAMP WHERE id = old.id;
END

但这有问题。每次在此表的记录上发生更新时,触发器都会在同一记录上触发新的更新。这应该再次触发触发,并再次导致无限循环的更新。

这真的会发生什么?触发器中的更新是否会再次触发触发器? 我可以避免在触发器内触发触发器吗?

4 个答案:

答案 0 :(得分:2)

实际上,我们在谈论SQLite,是吗?最初,不支持递归触发器(上面怀疑的无限循环)以防止出现此问题。它们现在受支持,但默认情况下已关闭。理论上,您可以使用"PRAGMA recursive-triggers = true"将其重新打开。

马的嘴在这里:SQLite Online Doc

答案 1 :(得分:1)

使用before update触发器:

CREATE TRIGGER last_update_trigger
BEFORE UPDATE
ON mytable
FOR EACH ROW
BEGIN
    set new.last_update = CURRENT_TIMESTAMP;
END;

或者,更好的是,使用默认值执行此操作。

编辑:

在SQLite中,您可以使用instead of触发器而不是之前的触发器执行此操作。类似的东西:

CREATE TRIGGER last_update_trigger
INSTEAD OF UPDATE
ON mytable
FOR EACH ROW
BEGIN
    update mytable
        set last_update = CURRENT_TIMESTAMP,
            col1 = new.col1,
            col2 = new.col2,
            . . .
END;

但是,我认为更好的选择是表定义中的default子句。

答案 2 :(得分:0)

对于UPDATE触发器,您可以指定它应触发的列。 只需将last_update列从该列表中删除:

CREATE TRIGGER MyTable_last_update
AFTER UPDATE OF col1, col2, etc ON MyTable
FOR EACH ROW
BEGIN
    UPDATE MyTable
    SET last_update = CURRENT_TIMESTAMP
    WHERE id = OLD.id;
END;

答案 3 :(得分:0)

John,使用WHEN子句,即使使用递归触发器也能正常工作。

PRAGMA recursive_triggers=1;
CREATE TRIGGER IF NOT EXISTS "mytable_last_update"
    AFTER UPDATE ON main.mytable FOR EACH ROW
    WHEN NEW.last_update < OLD.last_update
BEGIN
    UPDATE mytable SET last_update=CURRENT_TIMESTAMP WHERE oid=OLD.oid;
END;

我正在使用(strftime('%s','now')|| substr(strftime('%f','now'),4))而不是CURRENT_TIMESTAMP,用于在具有Javascript Date的网页上使用(方法。