Sql 更新主键时更新外键
我有三张桌子: 表1Sql 更新主键时更新外键,sql,oracle,oracle12c,database-trigger,Sql,Oracle,Oracle12c,Database Trigger,我有三张桌子: 表1 A1 primary key issue 表2 B1 primary key issue BA1 references table1 A1 表3 C3 primary key issue CB1 references table 2 B1 我想更新TABLE1.A1和BA1自动更新 更新TABLE2.B1 我创建了一个触发器: 此触发器用于表1 create or replace tigger 1_trg after update A1 on TABLE1 b
A1 primary key
issue
表2
B1 primary key
issue
BA1 references table1 A1
表3
C3 primary key
issue
CB1 references table 2 B1
我想更新TABLE1.A1
和BA1
自动更新
更新TABLE2.B1
我创建了一个触发器:
此触发器用于表1
create or replace tigger 1_trg
after update A1 on TABLE1
begin
update TABLE2
set BA1 := new.A1
where BA1:= old.A1
end;/
这一个用于表2
create or replace tigger 2_trg
after update B1 on TABLE2
begin
update TABLE3
set CB1:= new.B1
where CB1:= old.B1
end;/
但它不起作用,因为当
1\u-trg
与他一起触发2\u-trg
时,如果Oracle上没有更新级联
,这是有充分理由的。更多信息 处理这种情况的正确设计是定义一个单独的字段作为代理键。它不能是“自然钥匙”(=看起来独特但最终会改变的东西。自然钥匙的一个很好的例子是一个人的护照号码,不能用作主键) 尝试更新您的架构以添加1个主键列,例如由标识生成的数字。
一旦这样做了,你就不需要触发器了 编辑:突出显示下面的讨论。我发布的链接中的一个重要观点是,在这种情况下使用触发器可能会导致未定义的行为。
触发未定义行为的查询类型并不常见,但如果发生这种情况,将导致几乎无法调试的情况。与其使用格式错误的表名,不如使用类似于表a、B、C、列A1、A2、A3的名称。读了你的问题后我感到困惑(因为类似的表名和列名)…这就是为什么正确命名事物非常重要的原因。这很难阅读和理解。在表/列/触发器实际上包含/正在做的名称,而不是试图缩短它这么多。@ BaltoZoLoWoikk @马格努斯埃里克森SRY,我将修复ITI同意你,但现在我在应用程序的中间,如果有任何方式只是帮助:/嗯…我对你想做什么的问题超出了设计范围。Tom给出了一个更新触发器的示例,并说明它不起作用。他非常具体地说明了这个案件必须在不使用扳机的情况下处理。也许把整件事再读一遍。你认为你能调试像他所描述的那样的随机行为吗?不,我不这么认为@lau那么如果你真的需要更新主键而不能创建代理键,我会给你和他一样的建议:1。将外键更改为可延迟(=将在事务提交时检查它们,而不是在每个语句之后),2。在一个事务中使用2个查询处理更新,但不使用触发器。我不知道如何用触发器给你一个正确、安全的答案。我相信没有人会知道。谢谢你,我会在等待另一个想法的时候尽量做到这一点