使用触发器实现UPDATE CASCADE

时间:2012-09-11 01:33:14

标签: sql oracle triggers cascade updating

所以我有这个特殊属性(Sportcode)我被要求通过编写触发器来实现更新级联。此特定属性如下表所示:

运动

Sportcode       sport name                     sport event no
--------------- ------------------------------ ---------------
AR              Archery                               2 
AT              Athletics                             3 
BD              Badminton                             4 
BK              Basketball                            6 
BS              Baseball                              5 
BV              Beach Volleyball                     26 

如何使用触发器为Sportcode实现更新级联?


编辑:

我不确定这是否是我应该做的,但我想出了类似的东西:

CREATE OR REPLACE TRIGGER Sportcode_Upd_Cas
  BEFORE UPDATE OF Sportcode ON sports
  FOR EACH ROW
BEGIN
  UPDATE sports
    SET Sportcode =:new.Sportcode
    WHERE Sportcode =:old.Sportcode;

  DBMS_OUTPUT.PUT_LINE('Corresponding Sportcode in the Sports table has also been updated');
END; 

4 个答案:

答案 0 :(得分:1)

根据Oracle手册,您可以执行以下操作来完成UPDATE CASCADE效果,而无需向我们提供引用键:

create table p (p1 number constraint ppk primary key); 
create table f (f1 number constraint ffk references p); 
create trigger pt after update on p for each row begin
  update f set f1 = :new.p1 where f1 = :old.p1;
end;
/

答案 1 :(得分:1)

假设DISCIPLINE是父表,而DISCIPLINE_CHILD是子表:

CREATE OR REPLACE TRIGGER discipline_code_update
 AFTER UPDATE OF discipline_code ON discipline FOR EACH ROW
BEGIN
    UPDATE discipline_child
       SET discipline_code = :new.discipline_code
     WHERE discipline_code = :old.discipline_code;
END;
/

我添加了OF discipline_code,以便discipline_code语句中未包含UPDATE时触发器不会触发。

答案 2 :(得分:1)

如果DISCIPLINE_CODE是您桌面上的主键,您真的不应该更改它。请记住,主键有三个属性:

  1. 不是空
  2. 这是独一无二的,
  3. 永远不会改变。
  4. #3的原因正是您现在遇到的 - 如果更改主键,则还需要更改整个数据库中对该行的所有现有引用。这就是永远不应该更改主键的原因。

    Oracle将强制执行前两个,但我遇到的数据库都没有强制执行#3。如果您正在更改此表上的DISCIPLINE_CODE,那么按照定义它并不是一个主要的键,虽然您可以编写代码来执行此操作,但这是一个非常糟糕的主意。

答案 3 :(得分:0)

实施UPDATE CASCADE的一个陷阱是除了@ bob-jarvis之外提到的另一个原因。您必须小心多行更新。如果可能重用值,导致一个记录的AFTER值与另一个记录的BEFORE重叠,则结果是子行更新多次并迁移到另一个父级。

示例:

1
2

1
2

跑完后:

update parent set id = id + 1

你得到:

2
3

3
3

要么不重复使用键值,要么实现逻辑不要在触发器中两次更新同一行,或者更好的是,根本不使用此方法并使用真正的IMMUTABLE主键。