Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 更新主键时更新外键_Sql_Oracle_Oracle12c_Database Trigger - Fatal编程技术网

Sql 更新主键时更新外键

Sql 更新主键时更新外键,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

我有三张桌子:

表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
  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个查询处理更新,但不使用触发器。我不知道如何用触发器给你一个正确、安全的答案。我相信没有人会知道。谢谢你,我会在等待另一个想法的时候尽量做到这一点