2012-04-03 5 views
19

Sto provando a creare un trigger di database di base che elimina in modo condizionale le righe da database1.table1 quando viene eliminata una riga da database2.table2. Sono nuovo di trigger e speravo di imparare il modo migliore per farlo. Questo è quello che ho finora. Suggerimenti?SQL Server ON DELETE Trigger

CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    IF EXISTS (SELECT foo 
       FROM database2.dbo.table2 
       WHERE id = deleted.id 
       AND bar = 4) 

-- If there is a row that exists in database2.dbo.table2 
-- matching the id of the deleted row and bar=4, delete 
-- it as well. 

-- DELETE STATEMENT? 

GO 
+4

È necessario tenere conto del fatto che il trigger viene attivato ** una volta per istruzione ** (e ** NON ** una volta pe r fila come molti sviluppatori credono) e che la pseudo tabella 'Deleted' potrebbe contenere ** più righe ** (se la tua istruzione ha cancellato più righe) –

+0

@marc_s - Nel sistema, una sola riga potrebbe essere cancellata alla volta (applicazione front-end). Potresti approfondire cosa intendi. È semplice come cambiare 'DOVE id = deleted.id' a' DOVE id IN (SELECT id FROM cancellato) '? –

+2

@ShawnH. Sì, dovrebbe essere così semplice. Credo che Marc significhi che se in qualche modo venisse chiamata una cancellazione di massa da qualche parte, il trigger si sarebbe attivato una sola volta per l'intera istruzione anziché per riga, quindi l'uso di un 'IN' dovrebbe essere risolto in entrambi i casi. – Bridge

risposta

49
CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    DELETE FROM database2.dbo.table2 
    WHERE bar = 4 AND ID IN(SELECT deleted.id FROM deleted) 
GO 
+0

Grazie. Questo è molto più semplice e funziona come un fascino. –

2

INSERTED e DELETED sono tavoli virtuali. Devono essere utilizzati in una clausola FROM.

CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    IF EXISTS (SELECT foo 
       FROM database2.dbo.table2 
       WHERE id IN (SELECT deleted.id FROM deleted) 
       AND bar = 4) 
8

meglio usare:

DELETE tbl FROM tbl INNER JOIN deleted ON tbl.key=deleted.key 
1

Vorrei suggerire l'uso di exists invece di in perché in alcuni scenari che implica valori nulli the behavior is different, così

CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    DELETE FROM database2.dbo.table2 childTable 
    WHERE bar = 4 AND exists (SELECT id FROM deleted where deleted.id = childTable.id) 
GO