2014-01-19 83 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()方法。