【问题标题】:Deleting rows from multiple related tables从多个相关表中删除行
【发布时间】:2012-10-30 05:27:24
【问题描述】:

在标识符上有三个一一对应的表。我需要删除三个表中符合条件 A.ID = B.ID = C.ID 的所有记录

现在我按以下方式进行:

DECLARE
    CURSOR CUR IS 
        SELECT C.ID FROM A 
        INNER JOIN B ON A."ID" = B."ID" 
        INNER JOIN C ON B."ID" = C."ID"
        WHERE A.STATUS = 'ERROR';
    IDX NUMBER;
BEGIN
    FOR REC IN CUR LOOP 
        IDX := REC.ID;
        DELETE FROM C WHERE C."ID" = IDX;
        DELETE FROM B WHERE B."ID" = IDX;
        DELETE FROM A WHERE BP."ID" = IDX;
    END LOOP;
    COMMIT;
END;

大量数据,这种方式可以长期运行。有什么方法可以更快地删除?

【问题讨论】:

  • 为什么不把ID值放到一个临时表中,然后从连接到临时表的每个表中删除?
  • 如果您在这些表上有Foreign Keys,您可以添加ON DELETE CASCADE

标签: sql oracle plsql oracle10g cascading-deletes


【解决方案1】:

您可以创建一个 PL/SQL 类型来存储 ID。

CREATE TYPE t_ids AS TABLE OF NUMBER;

从表a 中删除所有符合条件的记录,并将ID 返回到该类型的变量中。然后删除 bc 中具有这些 ID 的所有记录。

DECLARE
  ids_to_delete   t_ids;
BEGIN
  DELETE FROM a
   WHERE a.status = 'ERROR'
     AND EXISTS ( SELECT 1 FROM b WHERE b.id = a.id )
     AND EXISTS ( SELECT 1 FROM c WHERE c.id = a.id )
  RETURNING a.id
  BULK COLLECT INTO ids_to_delete;

  DELETE FROM b
   WHERE id IN ( SELECT COLUMN_VALUE FROM TABLE( ids_to_delete ) );

  DELETE FROM c
   WHERE id IN ( SELECT COLUMN_VALUE FROM TABLE( ids_to_delete ) );
END;

这应该会执行得更好,因为它不需要循环并且在三个 SQL 语句中完成所有操作,而不是每个 ID 三个语句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    相关资源
    最近更新 更多