假设Oracle 10G中有两个表
TableA (Parent) --> TableB (Child)
TableA中的每一行在TableB中都有与其相关的几个子行。
我想删除TableA中的特定行,这意味着我必须先删除tableB中的相关行。
这将删除子条目
delete from tableB where last_update_Dtm = sysdate-30;
要删除子表中刚刚删除的行的父行,我可以这样做
Delete from TableA where not exists (select 1 from tableB where tableA.key=tableB.key);
上面还将删除子表中的行,其中(last_update_Dtm = sysdate-30)为false。TableA没有last_update_dtm列,因此如果没有子表中的条目,则无法知道要删除哪些行。
我可以在删除之前将键保存在子表中,但这似乎是一种昂贵的方法。删除两个表中的行的正确方法是什么?
为了更好地解释我要实现的目标,如果两个表之间没有约束,则以下查询将完成我要实现的目标。
Delete from tableA Where exists ( Select 1 from tableB where tableA.key=tableB.key and tableB.last_update_dtm=sysdate-30) Delete from tableB where last_update_dtm=systdate-30
两种可能的方法。
如果您有外键,请将其声明为on-delete-cascade并删除30天以上的父行。所有子行将被自动删除。
根据您的描述,您似乎知道要删除的父行,并且需要删除相应的子行。您是否尝试过这样的SQL?
delete from child_table where parent_id in ( select parent_id from parent_table where updd_tms != (sysdate-30)
-现在删除父表记录
delete from parent_table where updd_tms != (sysdate-30);
-—根据您的要求,看来您可能必须使用PL / SQL。我将看看是否有人可以为此发布一个纯SQL解决方案(在这种情况下,肯定是这样)。
declare v_sqlcode number; PRAGMA EXCEPTION_INIT(foreign_key_violated, -02291); begin for v_rec in (select parent_id, child id from child_table where updd_tms != (sysdate-30) ) loop -- delete the children delete from child_table where child_id = v_rec.child_id; -- delete the parent. If we get foreign key violation, -- stop this step and continue the loop begin delete from parent_table where parent_id = v_rec.parent_id; exception when foreign_key_violated then null; end; end loop; end; /