2012-08-07 4 views
0

J'ai 2 tables: A et BSupprimer plusieurs enregistrements de la table A et B avec un FK au tableau B

A contient les colonnes suivantes:

Id [uniqueIdentifier] -PK 
checkpointId [numeric(20,0)] 

B contient les éléments suivants:

Id [uniqueIdentifier] – PK 
A_id (FK, uniqueIdentifier) 

B a une référence à une colonne de A_id (FK)

La question: Je veux supprimer tous les enregistrements de la table A qui leur checkpoint_id est inférieure à X

delete from CheckpointStorageObject where checkpointIdentifierIdentifier <= 1000 

Mais je ne peux pas le faire depuis "The primary key value cannot be deleted because references to this key still exist"

J'ai essayé de supprimer la première de la table B sans rejoindre:

DELETE FROM CheckpointToProtectionGroup 
WHERE EXIST (SELECT * from CheckpointStorageObject 
      WHERE CheckpointStorageObject.CheckpointIdentifierIdentifier <= 1000) 

Mais cela n'a pas fonctionné.

comment puis-je le faire? Est-il possible de supprimer des deux tables avec une commande d'exécution?

Les enregistrements supprimés résultants peuvent être très volumineux (plus de 30 000 enregistrements dans chaque table).

Répondre

2

Essayez ceci:

d'abord supprimer de tableB:

delete from tableB where A_id IN (Select Id from tableA where checkpointId <= 1000) 

Et puis supprimer tableA:

delete from tableA where checkpointId <= 1000 
0

Vous devrez d'abord supprimer les entrées de la table B

delete from tableB where A_id IN (Select Id from tableA where checkpointIdentifierIdentifier <= 1000) 

Une fois cela fait, vous pouvez supprimer à partir du tableau A, en vérifiant les ID qui ne sont plus dans le tableau B

delete from tableA where Id not in (select A_id from tableB) 
0

Votre deuxième requête a quelques défauts:

  • il est EXISTS et non EXIST

  • vous devez spécifier la condition de jointure entre les deux tables. Dans les sous-requêtes corrélées comme celui-ci, vous ajoutez thi scondition dans la WHERE clause

  • il est usfeul aussi avoir des alias pour les tables, afin de réduire le code et le rendre plus lisible, en particulier avec de tels noms longs

  • de joignons les deux instructions d'une transaction, vous êtes donc certain qu'elle réussit - et supprimez des deux tables - ou échouez et ne supprimez rien. Si vous n'utilisez pas une transaction, la deuxième suppression peut échouer, si dans le peu de temps entre les deux suppressions, une ligne est insérée à la table B et fait référence à une ligne dans la table A que la deuxième instruction va essayer de supprimer .

, supprimez d'abord à partir du tableau B (CheckpointToProtectionGroup):

BEGIN TRANSACTION 

    DELETE FROM CheckpointToProtectionGroup AS b 
    WHERE EXISTS         --- EXISTS 
      (SELECT * 
      FROM CheckpointStorageObject AS a 
      WHERE a.id = b.A_id     --- join condition 
       AND a.CheckpointId <= 1000 
     ) ; 

puis de la table A (CheckpointStorageObject):

DELETE FROM CheckpointStorageObject 
    WHERE CheckpointId <= 1000 ; 

COMMIT TRANSACTION ; 
+0

J'editted le EXIST à EXISTE – Haimon

Questions connexes