Trigger

在 SQL99 中使用觸發器來強制執行功能依賴

  • October 17, 2019

問題如下:

對於 R(A, B, C, D, E),編寫一個觸發器以在插入時強制執行 AB->C。

這是我的解決方案:

CREATE TRIGGER fdEnforceInsert
BEFORE INSERT ON R
REFERENCING NEW ROW AS N
FOR EACH ROW
DECLARE counter INT
BEGIN 
 SELECT COUNT(*) INTO counter
 FROM R
 WHERE R.A = N.A AND R.B = N.B AND R. C <> N.C;
 IF(counter>0)
   THEN raise_exception ('AB->C on R was violated');
END;

我想問的一件事是在第二行中是否使用“之前”或“代替”?

instead of觸發器就是這樣。即使數據滿足約束,它也不會執行插入,因此不合適。

我知道你的例子是一個人為的例子,在現實生活中你將使用一個獨特的約束來強制執行這樣的規則,但是exists謂詞可能更有效:

BEGIN 
 IF EXISTS (
   SELECT 1 FROM R
   WHERE R.A = N.A AND R.B = N.B AND R. C <> N.C;
 )
   THEN raise_exception ('AB->C on R was violated');
END;

對於驗證觸發器,我發現 WHEN 子句是最直覺的:

CREATE TRIGGER fdEnforceInsert
BEFORE INSERT ON R
REFERENCING NEW ROW AS N
FOR EACH ROW
   WHEN ( EXISTS (
              SELECT 1 
              FROM R
              WHERE R.A = N.A 
                AND R.B = N.B 
                AND R. C <> N.C 
          )
        ) raise_exception ('AB->C on R was violated');

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