我可以在缺少 FOR EACH STATEMENT 的 SQLite 中插入新行之前構造一個刪除現有行的觸發器嗎?
這是我的 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 程式碼來刪除數據庫中不再需要的行,****然後再將新行插入數據庫。我更喜歡這種方法而不是觸發器,因為您只是在刪除不需要的數據。