2010-02-10 4 views
0

J'ai deux entités A et B qui sont liées dans une relation MxN via une table intermédiaire, ce qui fait un total de trois tables. Ma table de relations R a des contraintes FK non nulles sur les deux autres tables. Je veux supprimer toutes les entrées des tables A et B et R où A obéit à une contrainte (je peux fournir les identifiants dans une table par exemple).Supprimer toutes les entrées dans une relation MxN avec des contraintes FK non nulles

Est-il possible de supprimer des entrées des trois tables sans recourir à une procédure stockée et sans violer la contrainte non nulle?

Je veux quelque chose comme:

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

Avez-vous essayé la répondre? Si cela fonctionne pour vous, s'il vous plaît soyez si gentil de marquer ma réponse comme la solution. TIA, roland –

Répondre

2

Cela dépend. Si le fk entre r et b a été spécifié avec ON DELETE CASCADE, vous pouvez faire:

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; 

S'il n'y a pas de suppression en cascade, vous pouvez le faire avec une table temporaire:

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 
+0

Intéressant, je vais devoir essayer votre solution. C'est bien que la seule exigence est d'avoir

1

Vous pourriez le faire avec trois suppressions et en utilisant une table temporaire.

  • Tout d'abord, ajoutez tous les enregistrements à supprimer à une table temporaire. Ensuite, supprimez de votre tableau intermédiaire toutes les relations qui correspondent à votre contrainte. Troisièmement, supprimez de A tous les enregistrements qui n'existent pas dans la table intermédiaire.
  • Enfin, supprimez de B tous les enregistrements qui n'existent pas dans la table intermédiaire.

Exemple

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 
+1

mm, mais qu'en est-il des entrées dans a et b qui n'étaient pas dans r pour commencer? Vous avez juste axé ces ... –

+0

Roland a raison. Tous les enregistrements dans A et B sont nécessairement liés. Donc, à l'étape deux et trois, je finirais par supprimer des enregistrements qui ne doivent pas être supprimés –

+0

Vrai, j'ai supposé qu'il n'y en aurait pas. –

Questions connexes