删除具有非空FK约束的MxN关系中的所有条目

时间:2010-02-10 13:35:36

标签: sql many-to-many ansi-sql

我有两个实体A和B通过中间表在MxN关系中相关,因此总共有三个表。我的关系表R在其他两个表上具有不可为空的FK约束。

我想删除表A和B以及R中的所有条目,其中A遵守一些约束(例如,我可以在A表中提供ID)。

是否可以在不诉诸存储过程且不违反非空约束的情况下从三个表中删除条目?

我想要类似的东西:

delete from A a, B b, R r where a.id=r.fk_a and B.id=r.fk_B a

2 个答案:

答案 0 :(得分:2)

这取决于。如果使用ON DELETE CASCADE指定了r和b之间的fk,则可以执行以下操作:

START TRANSACTION;

DELETE FROM b
WHERE  id IN (
    SELECT r.b_id
    FROM       r
    INNER JOIN a
    ON         r.a_id = a.id
    WHERE      <some condition on a>
);

DELETE FROM a
WHERE      <some condition on a>;

COMMIT WORK;

如果没有级联删除,那么您可以使用临时表:

CREATE TEMPORARY TABLE to_be_deleted_from_b 
LIKE b;

START TRANSACTION;

INSERT INTO to_be_deleted_from_b
SELECT * 
FROM b
INNER JOIN r
ON         b.id = r.b_id
INNER JOIN a
ON         r.a_id = a.id
WHERE      <some condition on a>;

DELETE FROM r
WHERE  a_id IN (
    SELECT a.id
    FROM   a
    WHERE  <some condition on a>
);

DELETE FROM a
WHERE  <some condition on a>;

DELETE FROM b
WHERE b.id IN (
    SELECT id
    FROM   to_be_deleted_from_b
);

COMMIT WORK;

DROP TABLE to_be_deleted_from_b

答案 1 :(得分:1)

您可以使用三个删除并使用临时表来执行此操作。

  • 首先,将所有要删除的记录添加到临时表中。
  • 其次从您的中间表中删除所有符合您约束条件的关系。
  • 第三,从A中删除中间表中不存在的所有记录。
  • 最后,从B中删除中间表中不存在的所有记录。

示例

BEGIN TRAN

INSERT INTO #R
SELECT R.*
FROM R r
     INNER JOIN A a ON a.ID = r.fk_a
WHERE a.Column = 'AConstraint'

DELETE FROM R
FROM R r
     INNER JOIN A a ON a.ID = r.fk_a
WHERE a.Column = 'AConstraint'

DELETE FROM A
FROM A a
     INNER JOIN #R r ON r.fk_a = a.ID

DELETE FROM B
FROM B b
     INNER JOIN #R r ON r.fk_b = b.ID
WHERE r.ID IS NULL

DROP TABLE #R

COMMIT TRAN