簡體   English   中英

在表上實現語句級觸發器時,是否可以獲取所有受影響的行的舊記錄和新記錄?

[英]When implementing a statement-level trigger on a table, is it possible to obtain the OLD and NEW records for all affected rows?

在Oracle中,可以通過在CREATE TRIGGER語句中指定FOR EACH ROW子句來編寫行級觸發器:

CREATE TRIGGER MY_FANCY_TRIGGER
  BEFORE UPDATE ON MY_TABLE
  FOR EACH ROW
BEGIN
  IF :OLD.my_id_column > 4 AND :NEW.some_other_column <> 'foo' THEN
    -- ...
  END IF;
END;

這樣的觸發器使您可以查看每個受影響的行的之前之后的版本(分別為:OLD:NEW )。 例如,以下語句將使此觸發器對MY_TABLE每一行執行一次:

UPDATE MY_TABLE SET some_other_column = 'bar';

通過消除FOR EACH ROW子句,觸發器將成為語句級觸發器。 這意味着每個語句僅執行一次,無論該語句影響多少行(如果有)。 不幸的是,語句級觸發器沒有可用的:OLD:NEW變量(因為受影響的行數很多)。

是否可以在語句級觸發器內獲取所有受影響行的:OLD:NEW值? 我有一些處理,我希望每個語句只出現一次。

賈斯汀·凱夫(Justin Cave)提出的一種方法是,將行級觸發器中的信息存儲在單獨的程序包集合中。

如果您使用的是11g,則正確的方法是使用復合觸發器。 這樣可以避免創建用於保存鍵集合的單獨程序包-可以在觸發器本身中完成操作,

不直接,不。

標准方法是“三觸發解決方案”(在嘗試解決變異表問題時更常用)

  1. 創建一個包含表的鍵集合的包
  2. 創建一個before語句觸發器來初始化集合
  3. 創建一個行級觸發器,將鍵插入集合中。
  4. 創建一個after語句觸發器,該觸發器使用集合中的鍵進行處理

顯然,在您的情況下,如果您的行級觸發器沒有引起變異表錯誤,則這可能只會增加流程的復雜性。

正如josephj1989在下面指出的那樣,如果您恰好使用11g,則可以使用復合觸發器來簡化此操作。 您仍將聲明一個集合,將該集合填充到行級觸發器主體中,並在語句級觸發器中處理該集合。 但是,只有一個對象可以創建和管理,而不是多個對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM