2012-04-03 11 views
19

Próbuję utworzyć podstawowy wyzwalacz bazy danych, który warunkowo usuwa wiersze z database1.table1, gdy usunięty zostanie wiersz z database2.table2. Jestem nowy w wyzwalaczach i miałem nadzieję nauczyć się najlepszego sposobu na osiągnięcie tego. To jest to, co do tej pory miałem. Propozycje?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

Trzeba wziąć pod uwagę, że wyzwalacz jest uruchamiany ** raz na instrukcję ** (i ** NIE ** raz pe r wiersze, jak wierzy wielu programistów) i że pseudo-tabela 'Deleted' może zawierać ** wiele wierszy ** (jeśli twoja instrukcja usunęła wiele wierszy) –

+0

@marc_s - W systemie tylko jeden wiersz może być usunięty naraz (front-end aplikacji). Czy mógłbyś rozwinąć to, co masz na myśli. Czy tak proste jak zmiana "WHERE id = usunięty.id" na "WHERE id IN (SELECT id FROM deleted)"? –

+2

@ShawnH. Tak, powinno to być takie proste. Myślę, że Marc oznacza, że ​​jeśli jakiś masowy plik do usunięcia został wywołany gdzieś, wyzwalacz byłby uruchamiany tylko raz dla całego zdania, a nie dla wiersza, więc użycie 'IN' powinno uporządkować to w dowolny sposób. – Bridge

Odpowiedz

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

Dziękuję. Jest to o wiele prostsze i działa jak urok. –

2

INSERTED i DELETED są tablice wirtualne. Muszą być używane w klauzuli 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

Lepiej użyć:

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

Sugerowałbym użycie exists zamiast in ponieważ w niektórych scenariuszach Oznacza wartości null the behavior is different, więc

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 
Powiązane problemy