![](/img/trans.png)
[英]When implementing a statement-level trigger on a table, is it possible to obtain the OLD and NEW records for all affected rows?
[英]row-level trigger vs statement-level trigger
我很難理解“行級觸發器”和“語句級觸發器”之間的區別。
根據我的理解,在創建語句級觸發器的場景中,可以修改整個表。 行級觸發器只允許我修改受觸發器指定事件影響的元組。
這樣對嗎? 有人有這兩者的例子嗎?
主要區別不是觸發器可以修改什么,這取決於 DBMS。 觸發器(行或語句級別)也可以修改同一個或其他表的一個或多個行* ,並且可能具有級聯效果(觸發其他操作/觸發器),但當然所有這些都取決於 DBMS。
主要區別在於觸發器被激活的次數。 想象一下你有一個 100 萬行的表,你運行:
UPDATE t
SET columnX = columnX + 1
語句級觸發器將被激活一次(即使沒有行被更新)。 行級觸發器將被激活一百萬次,每更新一次行一次。
另一個區別是順序或激活。 例如,在 Oracle 中,將按以下順序激活 4 種不同類型的觸發器:
Before the triggering statement executes
Before each row that the triggering statement affects
After each row that the triggering statement affects
After the triggering statement executes
在前面的例子中,我們有類似的東西:
Before statement-level trigger executes
Before row-level trigger executes
One row is updated
After row-level trigger executes
Before row-level trigger executes
Second row is updated
After row-level trigger executes
...
Before row-level trigger executes
Millionth row is updated
After row-level trigger executes
After statement-level trigger executes
附錄
*關於觸發器可以修改哪些行:不同的DBMS對此有不同的限制,具體取決於DBMS中的具體實現或觸發器。 例如,在某些情況下,Oracle 可能會顯示“變異表”錯誤,例如,當行級觸發器從整個表中進行SELECT MAX(col) FROM tablename
( SELECT MAX(col) FROM tablename
)或者它修改其他行或整個表時相關/觸發的行。
當然,行級觸發器(在 Oracle 或其他中)修改其更改觸發它的行是完全有效的,這是一種非常常見的用途。 dbfiddle.uk中的示例。
其他 DBMS 可能對任何類型的觸發器可以做什么甚至提供什么類型的觸發器有不同的限制(例如,有些沒有BEFORE
觸發器,有些根本沒有語句級觸發器等)。
您可能希望觸發器操作在客戶端執行修改一百萬行的語句后執行一次(語句級觸發器)。 或者,您可能希望為修改的每一行觸發一次操作(行級觸發器)。
示例:假設您有一個觸發器,可以確保所有高中畢業生都能畢業。 也就是說,當一個大四的成績是 12 時,我們將其增加到 13,我們希望將成績設置為NULL
。
對於語句級觸發器,您會說,在增加等級語句運行后,檢查整個表一次以將等級 13 的任何 now 更新為NULL
。
對於行級觸發器,您會說,在更新每一行之后,如果新行的等級為 13,則將其更新為NULL
。
語句級觸發器如下所示:
create trigger stmt_level_trigger
after update on Highschooler
begin
update Highschooler
set grade = NULL
where grade = 13;
end;
行級觸發器如下所示:
create trigger row_level_trigger
after update on Highschooler
for each row
when New.grade = 13
begin
update Highschooler
set grade = NULL
where New.ID = Highschooler.ID;
end;
請注意,SQLite 不支持語句級觸發器,因此在 SQLite 中, FOR EACH ROW
是可選的。
語句級觸發器之間的主要區別如下:
語句級觸發器:基於名稱,如果執行任何語句,它就會起作用。 不取決於受影響的行數或任何行數。它只執行一次。 Exp :如果你想從部門 HR 更新每個員工的工資,最后你想知道有多少行受到影響意味着有多少工資增加了,然后使用語句級觸發器。 請注意,即使更新了零行,觸發器也會執行,因為如果執行了任何語句,則會調用語句級觸發器。 不管它是否影響任何行。
行級觸發器:每次當一行受到影響時執行。 如果受影響的行為零。沒有行級觸發器將執行。假設如果您想從部門為 HR 的 emp 表中刪除一名員工,並且您希望從 emp 表中刪除員工后,HR 部分的部門表中的計數應減少1.那么你應該選擇行級觸發器。
1)行級觸發器用於對行集執行操作,如插入、更新或刪除
例如:-您必須刪除一組行,同時為了審計目的,刪除的行也必須插入新表中;
2)語句級觸發器:-通常用於對您正在執行的事件施加限制。
例如:- 限制在晚上 10 點到早上 6 點之間刪除數據;
希望這可以幫助:)
dml 語句行級別觸發器僅針對 dml 語句的每一行的語句級觸發器
如果您想在修改行數時執行該語句,則可以通過語句級觸發器.. viseversa ...當您想對您的行數執行每次修改時,您需要去行級別觸發..
例如:語句級觸發器適用於修改表時..然后會影響更多的記錄。 和行級觸發器適用於每行更新或修改時..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.