Trigger

我可以在缺少 FOR EACH STATEMENT 的 SQLite 中插入新行之前構造一個刪除現有行的觸發器嗎?

  • January 19, 2017

這是我的 SQLite 架構:

CREATE TABLE IF NOT EXISTS deps (
   target TEXT NOT NULL,
   user TEXT NOT NULL,
   dependency TEXT NOT NULL);

CREATE INDEX IF NOT EXISTS targetUser ON deps (target, user);

換句話說,該deps表(一個依賴樹)旨在為每(target, user)對包含多行 - 具有相同對的所有行都是for some(target, user)的依賴。target``user

在我的應用程序中,使用者僅批量更新目標的依賴項。通過“批處理”,我的意思是我將 (1)DELETE所有包含 的行(target, user),然後 (2)INSERT新的行。

我想要一個觸發器來在 SQLite 數據庫中組合這兩個步驟,這樣在我為給定(target, user)的插入新行之前,數據庫會刪除這對的所有舊行。我想出了這個:

CREATE TRIGGER IF NOT EXISTS clearOldDeps BEFORE INSERT ON deps
   BEGIN
       DELETE FROM deps WHERE target = NEW.target AND user = NEW.user;
   END

可惜!SQLite 觸發器是 all FOR EACH ROW,它缺少FOR EACH STATEMENT,所以如果我在上面使用這個觸發器並為給定的(target, user)對插入一些行,插入的每一行都會刪除之前插入的行!

觀察:

sqlite> INSERT INTO deps VALUES ("t1", "u2", "e1"), ("t1", "u2", "e2"),("t1", "u2", "e3");
sqlite> select * from deps;
t1|u2|e3

我去添加三行,並希望("t1", "u2")刪除目標使用者對的任何預先存在的行,但我只插入了最後一行,因為它刪除了所有以前的行。

如果 SQLite 有FOR EACH STATEMENT觸發器,我懷疑這個觸發器可以使用它來工作,但既然它沒有,DELETE那麼我唯一的辦法是第一次INSERT嗎?有沒有更簡潔的方法?

請記住,這是一個精簡版的 SQL,並不支持所有操作。請參閱以下連結:

https://www.sqlite.org/lang_createtrigger.html

SQLite 支持BEFORE TRIGGER,它可以在採取進一步行動之前刪除行。該連結還提供了有關其工作原理的一些注意事項:

如果 BEFORE UPDATE 或 BEFORE DELETE 觸發器修改或刪除了已更新或刪除的行,則後續更新或刪除操作的結果未定義。此外,如果 BEFORE 觸發器修改或刪除了一行,則未定義原本會在這些行上執行的 AFTER 觸發器實際上是否會執行。

請參閱連結以了解有關 SQLite 觸發器的其他詳細資訊。

當然,您可以編寫 SQLite 程式碼來刪除數據庫中不再需要的行,****然後再將新行插入數據庫。我更喜歡這種方法而不是觸發器,因為您只是在刪除不需要的數據。

引用自:https://dba.stackexchange.com/questions/161557