2012-04-03 6 views
19

Я пытаюсь создать базовый триггер базы данных, который условно удаляет строки из базы данных1.table1, когда строка из базы данных2.table2 удаляется. Я новичок в триггерах и надеялся узнать лучший способ добиться этого. Это то, что у меня есть до сих пор. Предложения?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

Вам нужно учесть, что триггер запускается ** один раз за утверждение ** (и ** NOT ** один раз pe r row, как полагают многие разработчики) и что псевдо-таблица «Deleted» может содержать ** несколько строк ** (если ваш оператор удалил несколько строк) –

+0

@marc_s - в системе только одна строка может быть удалена за раз (прикладной интерфейс). Не могли бы вы рассказать о том, что вы имеете в виду. Это так же просто, как изменение 'WHERE id = deleted.id' на' WHERE id IN (SELECT id FROM deleted) '? –

+2

@ShawnH. Да, это должно быть так просто. Я думаю, что Marc означает, что если каким-то образом вызывается массовое удаление, откуда-то запускается только один раз для всего оператора, а не для строки, поэтому использование 'IN' должно сортировать его в любом случае. – Bridge

ответ

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

Спасибо. Это намного проще и работает как шарм. –

2

INSERTED и DELETED виртуальные таблицы. Они должны использоваться в предложении 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

Лучше использовать:

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

Я хотел бы предложить использовать exists вместо in, потому что в некоторых случаях это подразумевает нулевые значения the behavior is different, так

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