Sql 如何更新具有外键限制的两个表的行

Sql 如何更新具有外键限制的两个表的行,sql,postgresql,Sql,Postgresql,我有两个表:一个是国外参考表,比如说表a,另一个是数据表,比如说表b。 现在,当我需要更改表b中的数据时,我受到表a的限制。 如何更改两个表中的“rid”而不获得此消息 错误:在表“表a”上插入或更新与外键冲突 约束“fk_boo_kid”SQL状态:23503 详细信息:表“表b”中没有键(kid)=(110) 更新两个表的查询示例: UPDATE table b table a SET rid = 110 WHERE rid =1 表b +-----+-------+-------+ |r

我有两个表:一个是国外参考表,比如说表a,另一个是数据表,比如说表b。 现在,当我需要更改表b中的数据时,我受到表a的限制。 如何更改两个表中的“rid”而不获得此消息

错误:在表“表a”上插入或更新与外键冲突 约束“fk_boo_kid”SQL状态:23503

详细信息:表“表b”中没有键(kid)=(110)

更新两个表的查询示例:

UPDATE table b table a SET rid = 110 WHERE rid =1
表b +-----+-------+-------+ |rid | ride | qunta| +-----+-------+-------+ |1 |车| 1| |2 |自行车| 1| +-----+-------+-------+ 表a +-----+-----+------------+ |孩子的约会| +-----+-----+------------+ | 1 | 1 | 20-12-2015 | | 2 | 2 | 20-12-2015 | +-----+-----+------------+
这篇评论太长了

您应该真正解释为什么要将ID更改为其他内容。主键确实应该被视为不可变的,因此它们可以标识表中的行以及随时间变化的行


如果出于某种原因确实需要更改它们,请为相关表定义适当的外键约束。然后在更新cascade时将外键定义为
。这将“cascade”当主键更改时,对所有受影响的更改所做的更改。

您不能更新/删除表B中的主键,因为主键在表a中使用

如果>>

  • 必须删除表A中使用主键表B的行
  • 您可以删除表B中的行

  • 在Postgres中,您可以使用可写CTE在一条语句中更新两个表

    假设此表设置:

    create table a (rid integer primary key, ride text, qunta integer);
    create table b (kid integer primary key, rid integer references a, date date);
    
    CTE将是:

    with new_a as (
      update a 
        set rid = 110
      where rid = 1
    )
    update b 
      set rid = 110 
    where rid = 1;
    
    由于(不可延迟的)外键是在语句级别上计算的,并且主键和外键在同一语句中都发生了更改,所以这是有效的


    SQLFiddle:

    @H35am。我已经删除了无关的数据库标记。请随意为您实际使用的数据库添加一个或多个。只要您启用了外键,您就必须遵守它们。因此,要么在操作期间禁用外键,这通常在数据库导入和批量操作中完成,要么在操作期间添加一个伪键(在活动系统中很危险,在批处理操作中很棘手),使用Postgres和Oracle,您可以使用延迟约束来完成。在Postgres中,你可以用一句话就能做到。非常感谢你,我读了很多关于在执行这样的操作之前必须删除外键的文章,但是你的方法非常有效。顺便说一句,我正在使用Postgresql,我在标签中有它,但Gordon Linoff删除了我的tags@H35am:Gordon取下标签,因为这里提到了三种不同的DBMS,如果您没有真正使用所有这些DBMS,通常会得到对您没有帮助的答案them@a_horse_with_no_name当已经知道表b引用了表a时,这非常好。但如果这不是事先知道的呢?男孩是在一个生产数据库问题后救了我的。我能够同时更新8个表。对于其他人来说,它的工作形式是“q为(…),a为(…),b为(…)更新c…”天才!爱死它了!
    with new_a as (
      update a 
        set rid = 110
      where rid = 1
    )
    update b 
      set rid = 110 
    where rid = 1;