Sql 从约束相关的两个表中删除行
我们有两张桌子:Sql 从约束相关的两个表中删除行,sql,oracle,plsql,Sql,Oracle,Plsql,我们有两张桌子: HUSBANDS --------------- id name surname age WIFES --------------- id name surname age husbandId --(with constrain -> HUSBANDS.ID) 假设我们需要写一个程序,把60岁以上的妻子和他们的丈夫一起带走;) 使用典型的SQL语句可以很好地做到这一点,但在Oracle中,不可能在一个delete语句中删除两个
HUSBANDS
---------------
id
name
surname
age
WIFES
---------------
id
name
surname
age
husbandId --(with constrain -> HUSBANDS.ID)
假设我们需要写一个程序,把60岁以上的妻子和他们的丈夫一起带走;)
使用典型的SQL语句可以很好地做到这一点,但在Oracle中,不可能在一个delete语句中删除两个表中的行,对吗?所以
我们不能这样做:
PROCEDURE remove_old_wifes() IS
BEGIN
DELETE FROM husbands WHERE id IN (SELECT husbandId FROM wifes WHERE age >= 60);
DELETE FROM wifes WHERE age >= 60;
END;
因为约束
另一方面,下面提到的解决方案也是错误的:
PROCEDURE remove_old_wifes() IS
BEGIN
DELETE FROM wifes WHERE age >= 60;
DELETE FROM husbands WHERE id IN (SELECT husbandId FROM wifes WHERE age >= 60);
END;
因为当我们先解除妻子的职务时,没有一个丈夫会被解除职务
这个案例的典型解决方案是什么
重要提示:我无法设置级联。如果表中不允许“未婚丈夫”,您可以先删除妻子,然后删除所有不再有妻子的丈夫。如果临时不一致是一个问题,您可能希望将删除内容包装在事务中
PROCEDURE remove_old_wifes() IS
BEGIN
DELETE FROM wifes WHERE age >= 60;
DELETE FROM husbands WHERE id NOT IN (SELECT husbandId FROM wifes);
END;
您可以首先使用丈夫没有妻子的指示器更新丈夫。对于您的数据,让我们使用
age=-1
。然后从妻子处删除[sic],然后从丈夫处删除
update husbands
set age = -1
where id in (select husbandId from wifes where age >= 60);
delete from wifes where age >= 60;
delete from husbands where age = -1;
在Oracle中有许多外键子句。 例如,您可以在外键中包含“on delete cascade”子句:
alter table WIFES
add foreign key (husbandId )
references HUSBANDS(id)
on delete cascade;
有了这个子句,您可以只使用一个delete来删除两个表中的行。
因此,您的程序将是:
PROCEDURE remove_old_wifes() IS
BEGIN
DELETE FROM husbands WHERE id IN (SELECT husbandId FROM wifes WHERE age >= 60);
END;
如果无法设置on delete cascade子句,则应使用全局临时表,例如:
create table gtt_id( id number) on commit delete rows;
PROCEDURE remove_old_wifes() IS
BEGIN
insert into gtt_id SELECT husbandId FROM wifes WHERE age >= 60;
delete FROM wifes WHERE age >= 60
DELETE FROM husbands WHERE id IN (SELECT id FROM gtt_id);
END;
你为什么不能设置cascade?@GordonLinoff,因为我不是schema的自动生成者,我对此有禁令;)在婚姻关系(丈夫和妻子)的情况下,这可能是有效的,但我需要解决丈夫ID可以为空的问题(可选)。@LuisSuarez你能在你的问题中添加一些样本数据来说明你的意思吗?