1

So I have this particular attribute (Sportcode) I am asked to implement update cascade by writing a trigger. this particular attribute is in the table below:

Sports

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 

How do I use a trigger to implement update cascade for Sportcode?


EDIT:

I'm not sure whether this is what i am supposed to do but i came up with something like this:

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

4 回答 4

1

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

  1. 它不为空
  2. 它是独一无二的,并且
  3. 它永远不会改变。

#3 的原因正是您现在遇到的 - 如果您更改主键,那么整个数据库中对该行的所有现有引用也需要更改。这就是为什么不应该更改主键的原因。

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

于 2012-09-11T11:15:55.953 回答
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

于 2012-09-11T02:30:29.790 回答
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;
/
于 2012-09-11T01:42:56.323 回答
0

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

例子:

家长

1
2

孩子

1
2

运行后:

update parent set id = id + 1

你得到:

家长

2
3

孩子

3
3

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

于 2017-01-06T00:27:26.837 回答