2010-09-07 4 views
28

Angenommen, es gibt eine Haupttabelle, die einen Primärschlüssel enthält, und eine andere Tabelle, die einen Fremdschlüssel für diese Haupttabelle enthält. Wenn wir also die Zeile der Haupttabelle löschen, wird auch die untergeordnete Tabelle gelöscht.So löschen Sie Zeilen in Tabellen, die Fremdschlüssel für andere Tabellen enthalten

Wie schreibe ich diese Abfrage?

+0

@pradeep: Welche Datenbank verwenden Sie? –

+1

datenbank von mir verwendet: sql sever 2008 –

+0

Ich möchte einfache Abfrage Ich möchte nicht speichern Verfahren –

Antwort

19

Von Ihrer Frage, ich denke, es ist sicher anzunehmen, Sie haben CASCADING DELETES eingeschaltet.
Alles, was in diesem Fall erforderlich ist, ist

DELETE FROM MainTable 
WHERE PrimaryKey = ??? 

Sie Datenbank-Engine Pflege Löschen der entsprechenden Verweisen auf Aufzeichnungen nehmen.

+0

sql Server 2008 –

+1

In oracle müssen Sie zuerst die 'Abhängigkeiten' löschen und dann die Eltern löschen. –

+0

Und was passiert, wenn die referenzierte Tabelle eine Haupttabelle für andere Tabellen ist und ein FK mit Löschregel: Keine Aktion. Lässt der Server Datensätze von der aktuellen MainTable löschen, wo wir die Regel löschen auf: Cascade? Danke –

7

Sie können eine Fremdschlüsseleinschränkung mit der Option delete kaskade wie unten gezeigt ändern. Dadurch werden chind-Tabellenzeilen gelöscht, die sich auf Master-Tabellenzeilen beziehen.

ALTER TABLE MasterTable 
ADD CONSTRAINT fk_xyz 
FOREIGN KEY (xyz) 
REFERENCES ChildTable (xyz) ON DELETE CASCADE 
+0

Das ist großartig, aber nicht immer eine Lösung, wenn niedrige SQLite-Versionen unterstützt werden, was beispielsweise bei der Unterstützung von Android API 4 der Fall ist, die nur mit einer SQLite geliefert wird, bevor sie Fremdschlüsselunterstützung hinzufügen. – Daniel

16

Zuerst wird, wie eine einmalige Daten Schrubben Übung, löschen die verwaisten Zeilen z.B.

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

Zweitens als einmalige Schema-Änderung Übung fügen die ON DELETE CASCADE referenziellen Aktion auf den Fremdschlüssel auf der verweisenden Tabelle z.B.

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; 

Dann werden für immer Zeilen in den referenzierenden Tabellen automatisch gelöscht, wenn ihre referenzierte Zeile gelöscht wird.

4

Wenn Sie mehrere zu löschende Zeilen haben und die Struktur Ihrer Tabellen nicht ändern möchten, können Sie den Cursor verwenden: . 1-Zuerst müssen Sie die zu löschenden Zeilen auswählen (in einem Cursor) 2-Dann löschen Sie für jede Zeile im Cursor die referenzierenden Zeilen und löschen danach die Zeile selbst.

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 

Hoffnung ist nützlich

+0

Während dies funktioniert, wenn Sie T-SQL verwenden, ist die Leistung auf Cursors wirklich schlecht. – Corv1nus

-1

Benötigen Sie den Fremdschlüssel Option gesetzt als auf Kaskade löschen ... in Tabellen, die Fremdschlüsselspalten enthält .... Es müssen zum Zeitpunkt der Tabellenerstellung festlegen oder später hinzufügen mit ALTER Tabelle

+4

Und warum posten Sie etwas, das bereits in anderen Antworten gegeben wurde? –

Verwandte Themen