2010-09-07 10 views
28

Supponiamo che ci sia una tabella principale contenente una chiave primaria e che ci sia un'altra tabella che contiene una chiave esterna per questa tabella principale. Quindi se cancelliamo la riga della tabella principale elimineremo anche la tabella figlio.Come eliminare righe in tabelle che contengono chiavi esterne ad altre tabelle

Come scrivere questa query?

+0

@pradeep: quale database si utilizza? –

+1

database usato da me: sql sever 2008 –

+0

Voglio query semplice Non voglio usare la procedura di memorizzazione –

risposta

19

Dalla tua domanda, penso che sia sicuro assumere CASCADING DELETES attivato.
Tutto ciò che serve in questo caso è

DELETE FROM MainTable 
WHERE PrimaryKey = ??? 

motore di database si prenderà cura di eliminare i record che fanno riferimento corrispondenti.

+0

sql Server 2008 –

+1

In Oracle, sarà necessario prima eliminare le 'dipendenze' e quindi eliminare il genitore. –

+0

E cosa succederà se la tabella di riferimento è una tabella principale per altre tabelle e ci sono un FK con la regola Elimina: Nessuna azione. Il server permetterà di cancellare il record dalla MainTable corrente dove impostiamo Delete rule a: Cascade? Grazie –

7

È possibile modificare un vincolo di chiave esterna con l'opzione Elimina cascata come mostrato di seguito. Questo cancellerà le righe della tabella dei chind relative alle righe della tabella principale quando eliminate.

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

Questo è ottimo ma non è sempre una soluzione quando si supportano versioni SQLite basse, ad esempio nel supportare l'API 4 di Android che viene fornita solo con SQLite appena prima di aggiungere il supporto per le chiavi esterne. – Daniel

16

In primo luogo, come un esercizio di dati-scrubbing di una volta, eliminare le righe orfani per esempio

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

secondo luogo, come esercizio schema-alterazione di una volta, aggiungere l'azione referenziale ON DELETE CASCADE alla chiave esterna sulla tabella di riferimento esempio

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; 

Poi, per sempre, righe nelle tabelle di riferimento verranno eliminati automaticamente quando la loro riga di riferimento viene eliminata.

4

Se si sono moltiplicate le righe da eliminare e non si desidera modificare la struttura delle tabelle è possibile utilizzare il cursore. 1-Per prima cosa è necessario selezionare le righe da eliminare (in un cursore) 2-Quindi per ogni riga del cursore si eliminano le righe di riferimento e successivamente si elimina la riga da solo.

Es:

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

speranza è utile

+0

Mentre funziona, se stai usando T-SQL le prestazioni sui cursori sono davvero pessime. – Corv1nus

-1

necessario impostare l'opzione di chiave esterna come sulla eliminare cascata ... nelle tabelle che contiene le colonne chiave esterna .... Ha bisogno per impostare al momento della creazione della tabella o aggiungere successivamente utilizzando la tabella ALTER

+4

E perché pubblicare qualcosa che è già stato dato in altre risposte ancora una volta? –

Problemi correlati