Удалить все записи в отношении MxN с ненулевыми ограничениями FK - PullRequest
0 голосов
/ 10 февраля 2010

У меня есть две сущности A и B, которые связаны в отношении MxN через промежуточную таблицу, в результате чего получается три таблицы. Моя таблица отношений R имеет необнуляемые ограничения FK для двух других таблиц.

Я хочу удалить все записи из таблиц A и B и R, где A подчиняется некоторому ограничению (например, я могу указать идентификаторы в таблице A).

Можно ли удалить записи из трех таблиц, не прибегая к хранимой процедуре и не нарушая ненулевое ограничение?

Я хочу что-то вроде:

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

Ответы [ 2 ]

2 голосов
/ 10 февраля 2010

Это зависит. Если бы fk между r и b был указан с ON DELETE CASCADE, вы могли бы сделать:

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 голос
/ 10 февраля 2010

Это можно сделать с помощью трех удалений и использования временной таблицы.

  • Сначала добавьте все подлежащие удалению записи во временную таблицу.
  • Во-вторых, удалите из своей таблицы-посредника все отношения, которые соответствуют вашему ограничению.
  • В-третьих, удалить из 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
...