所以我有这个特殊属性(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;
答案 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是您桌面上的主键,您真的不应该更改它。请记住,主键有三个属性:
#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主键。