web-dev-qa-db-fra.com

Comment supprimer des lignes dans des tables contenant des clés étrangères vers d'autres tables

Supposons qu'il existe une table principale contenant une clé primaire et qu'il existe une autre table contenant une clé étrangère à cette table principale. Donc, si nous supprimons la ligne de la table principale, la table enfant sera également supprimée.

Comment puis-je écrire cette requête?

34
pradeep

D'après votre question, je pense qu'il est prudent de supposer que vous avez CASCADING DELETES activé.
Dans ce cas, tout ce qui est nécessaire est

DELETE FROM MainTable
WHERE PrimaryKey = ???

Votre moteur de base de données se chargera de supprimer les enregistrements de référence correspondants.

22

Tout d'abord, en tant qu'exercice unique de nettoyage des données, supprimez les lignes orphelines, par ex.

DELETE 
  FROM ReferencingTable 
 WHERE NOT EXISTS (
                   SELECT * 
                     FROM MainTable AS T1
                    WHERE T1.pk_col_1 = ReferencingTable.pk_col_1
                  );

Deuxièmement, comme exercice ponctuel de modification de schéma, ajoutez le ON DELETE CASCADE action référentielle sur la clé étrangère de la table de référence, par exemple.

ALTER TABLE ReferencingTable DROP 
   CONSTRAINT fk__ReferencingTable__MainTable;

ALTER TABLE ReferencingTable ADD 
   CONSTRAINT fk__ReferencingTable__MainTable 
      FOREIGN KEY (pk_col_1)
      REFERENCES MainTable (pk_col_1)
      ON DELETE CASCADE;

Ensuite, à tout jamais, les lignes des tables référentes seront automatiquement supprimées lorsque leur ligne référencée sera supprimée.

20
onedaywhen

Vous pouvez modifier une contrainte de clé étrangère avec l'option delete cascade, comme indiqué ci-dessous. Cela supprimera les lignes de la table chind associées aux lignes de la table principale lors de la suppression.

ALTER TABLE MasterTable
ADD CONSTRAINT fk_xyz 
FOREIGN KEY (xyz) 
REFERENCES ChildTable (xyz) ON DELETE CASCADE 
8
Anil Soman

Si vous avez plusieurs lignes à supprimer et que vous ne souhaitez pas modifier la structure de vos tables, vous pouvez utiliser le curseur. 1-Vous devez d’abord sélectionner les lignes à supprimer (dans un curseur) 2-Ensuite, pour chaque ligne du curseur, vous supprimez les lignes qui font référence, puis vous supprimez la ligne elle-même.

Ex:

--id is primary key of MainTable
    declare @id int
    set @id = 1
    declare theMain cursor for select FK from MainTable where MainID = @id
    declare @fk_Id int
    open theMain
    fetch next from theMain into @fk_Id
    while @@fetch_status=0
    begin
        --fkid is the foreign key 
        --Must delete from Main Table first then child.
        delete from MainTable where fkid = @fk_Id
        delete from ReferencingTable where fkid = @fk_Id
        fetch next from theMain into @fk_Id
    end
    close theMain
    deallocate theMain

l'espoir est utile

4
Milena