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