微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

一步删除子表和父表中的行

如何解决一步删除子表和父表中的行

我有一个这样的查询

DELETE FROM reminder
 WHERE EXISTS (SELECT r.ROWID,r.id,r.name,r.remark,u.user_id,u.deadline,u.audt_creation_date,d.next_test_date_internal,t.test_internal_external
               FROM   reminder r,reminder_users u,device d,device_test t
               WHERE  r.id = u.reminder_id
                      AND u.receipt = 0
                      AND ( Regexp_replace(r.origin_values,'[^0-9]','') ) = d.id
                      AND d.next_test_int_id = t.id
                      AND t.test_internal_external = 0
                      AND r.name LIKE '%Interne%'
                      AND r.name NOT LIKE '%Externe%'
                      AND u.deadline <> d.next_test_date_internal
                      AND u.deadline > SYSDATE
                      AND reminder.id = r.id
               GROUP  BY r.ROWID,t.test_internal_external); 

第二个查询是这样的:

DELETE FROM reminder_users
WHERE  EXISTS (SELECT u.reminder_id,'') ) = d.id
                      AND d.next_test_int_id = t.id
                      AND t.test_internal_external = 0
                      AND r.name LIKE '%Interne%'
                      AND r.name NOT LIKE '%Externe%'
                      AND u.deadline <> d.next_test_date_internal
                      AND u.deadline > SYSDATE
                      AND reminder_users.reminder_id = u.reminder_id
               GROUP  BY u.reminder_id,t.test_internal_external); 

表 REMINDER 是父表,表 REMINDER_USERS 包含子记录。我无法使用级联删除选项创建外键,因为只能删除某些子记录和父记录。

当我尝试运行第一个查询时,我收到 ora 02292-Error(ora-02292 完整性约束违反 - 找到子记录)。所以理论上我必须先运行第二个查询,以便之后删除父表中的相应行。但是当我先运行第二个查询时,第一个查询中的select显然返回0值,因为我之前删除了子记录。

谁能提供一段代码,一步删除子记录和相应的父记录?

提前致谢!

解决方法

使用逻辑删除,在父表中创建一个列,你可以让它不可见,我猜你有一个外键来确保父子引用完整性。

因此,此列将根据您的条件(无论您必须删除行的任何条件)判断该行是否已被逻辑删除。 创建一个触发器,如果​​逻辑删除设置为 1,该触发器将被触发,该触发器将删除子表中的行,并创建第二个触发器,该触发器将跟随您的第一个触发器删除父表中的行。

,

最简单的选择就是在循环中进行删除。当然,您将进行逐行操作,这通常不是最有效的。但对于大多数事情来说,它已经足够快了

for rows_to_delete in (**your select statement**)
loop
  delete from child
   where parent_id = rows_to_delete.parent_id;

  delete from parent
   where parent_id = rows_to_delete.parent_id;
end loop;

为了提高效率,您可以执行 delete with a returning into

create table parent (
  parent_id integer primary key,parent_val varchar2(10)
 );

create table child (
  child_id integer primary key,parent_id integer references parent( parent_id),child_val varchar2(10)
);

create type parent_tbl is table of integer;

declare
  l_parent_keys_to_remove parent_tbl;
begin
  delete from child
   where child_val in ('aaa','ccc')
   returning parent_id
       bulk collect into l_parent_keys_to_remove;
       
  delete from parent
   where parent_id member of l_parent_keys_to_remove;
end;
/

或者你可以select the rows to delete into the collection first and then use the collection for both deletes

declare
  l_parent_keys_to_remove parent_tbl;
begin
  select parent_id
    bulk collect into l_parent_keys_to_remove
    from parent
   where parent_val in ('a','c');
   
  delete from child
   where parent_id member of l_parent_keys_to_remove;
       
  delete from parent
   where parent_id member of l_parent_keys_to_remove;
end;
/

请注意,如果您要删除的父行可能没有关联的子行,则您需要执行 select 方法。如果您只是先针对子表发出 delete,则 returning into 将不会为没有子表的父表提供值。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。