2012-04-03 24 views
19

Estoy tratando de crear un desencadenante de base de datos básico que condicionalmente elimine filas de database1.table1 cuando se elimina una fila de database2.table2. Soy nuevo en los factores desencadenantes y esperaba aprender la mejor manera de lograr esto. Esto es lo que tengo hasta ahora. Sugerencias?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

Es necesario para tener en cuenta que el activador se activa ** una vez por estado ** (y ** NO ** una vez que r row como muchos desarrolladores creen) y que la pseudo tabla 'Deleted' podría contener ** varias filas ** (si su instrucción eliminó varias filas) –

+0

@marc_s - En el sistema, solo una fila podría eliminarse a la vez (front-end de la aplicación). ¿Podría explicarme más sobre lo que quiere decir? ¿Es tan simple como cambiar 'WHERE id = deleted.id' a' WHERE id IN (SELECT id FROM deleted) '? –

+2

@ShawnH. Sí, debería ser así de simple. Creo que Marc quiere decir que si de alguna manera se llamara una eliminación masiva desde algún lugar, el disparador solo dispararía una vez para toda la instrucción en lugar de por línea, por lo que usar un 'IN' debería ordenarlo de cualquier manera. – Bridge

Respuesta

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

Gracias. Esto es mucho más simple y funciona como un encanto. –

2

INSERTED y DELETED son tablas virtuales. Deben usarse en una cláusula 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

mejor utilizar:

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

Yo sugeriría el uso de exists en lugar de in porque en algunos escenarios que implica valores nulos the behavior is different, por lo

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