2014-01-19 84 views
2

我正试图在sqlite中实现“ON UPDATE CURRENT_TIMESTAMP”MySQL特性的等效功能。 我的想法是使用触发器这样的:sqlite触发器触发其他触发器吗?

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 

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

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

回答

2

事实上,我们正在谈论的SQLite,是吗?最初,递归触发器(上面怀疑的无限循环)不是专门为了防止这个问题而被支持的。他们现在支持,但默认关闭。理论上,您可以用"PRAGMA recursive-triggers = true"将它们重新打开。

马的嘴是在这里:SQLite Online Doc

+0

谢谢!那就是我正在寻找的信息。 –

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子句。

+0

看起来这不像是句法正确的。根据http://www.sqlite.org/lang_createtrigger.html文档,我需要在BEGIN和END之间有一条UPDATE语句。这应该导致我在原始帖子中描述的相同问题:无限循环。触发循环的实际原始更新永远不会发生。 –

+0

这个问题被标记为MySQL,这是MySQL允许的语法(http://dev.mysql.com/doc/refman/5.7/en/create-trigger.html)。 SQLite语法可能有所不同。 –

+0

对不起,我试图用sqlite模拟一个MySQL特性。我不需要MySQL解决方案,因为MySQL已经用一个简单的'ON UPDATE CURRENT_TIMESTAMP'语句来完成这个任务。我将删除mysql标签,因为它很混乱。 –

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; 
+0

是的,我想过,但我希望能够在表中添加列,并且触发器仍然适用于更新新列。 –

0

约翰,使用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' 的, '现在')|| SUBSTR(的strftime( '%F', '现在'),4)),而不是CURRENT_TIMESTAMP,使用网页上用Javascript Date()方法。