2012-03-24 34 views
7

Estoy haciendo algunos ajustes a una aplicación heredada creada en SQL Server 2000, no hace falta decir que solo quiero hacer el mínimo absoluto en el temor de que todo se desmorone.EN VEZ DE ACTUALIZACIÓN Disparador: ¿es esto posible?

Tengo una gran tabla de usuarios, tbUsers, con un indicador BIT para IsDeleted. Quiero archivar todos los registros actuales y futuros de IsDeleted = 1 en mi tabla de archivos tbDeletedUsers.

Mover los usuarios actualmente eliminados es sencillo, sin embargo, quiero una manera de mover a los futuros usuarios donde se establece el indicador IsDeleted. Podría usar un desencadenador AFTER estándar en la columna; sin embargo, planeo agregar algunas restricciones a la tabla tbUser que violaría esto, ¿qué me gustaría que mi desencadenador INSTEAD OF UPDATE active y mueva el registro a la tabla de archivo?

Supongo que mi pregunta es ... ¿es posible activar un disparador EN LUGAR DE ACTUALIZAR en la actualización de una columna individual? Esto es lo que tengo hasta ahora:

CREATE TRIGGER trg_ArchiveUsers 
INSTEAD OF UPDATE ON tbUsers 
AS 
    BEGIN 
     ... 
    END 
GO 

¡Si es así, un ejemplo (SQL 2000 compatible) sería muy apreciado!

Respuesta

12

Utilizando la prueba UPDATE(columnname), se puede comprobar en un disparador si una columna específica ha sido actualizada (y luego tomar acciones específicas), pero no se puede tener un disparador fuego sólo en la actualización de una columna específica . Se activará tan pronto como se realice la actualización, independientemente del hecho de qué columna fue el objetivo de la actualización.

Por lo tanto, si usted piensa que tiene que utilizar un disparador INSTEAD OF UPDATE, tendrá que implementar dos tipos de acciones en ella:

1) insertar en tbDeletedUsers + borrar de tbUsers - cuando IsDeleted se actualiza (o , más exactamente, actualizado y establecido en 1);

2) actualiza tbUsers normalmente - cuando IsDeleted no está actualizado (o actualizado, pero no se establece en 1).

Debido a que más de una fila se puede actualizar con una sola instrucción UPDATE, es posible que también tenga que tomar en cuenta que algunas filas podrían tener IsDeleted conjunto de 1 y otros no.

No soy un gran fan de INSTEAD OF desencadenantes, pero si he tenido que usar uno para una tarea como la suya, podría omitir la prueba UPDATE() e implementar el gatillo de esta manera:

CREATE TRIGGER trg_ArchiveUsers 
ON tbUsers 
INSTEAD OF UPDATE 
AS 
BEGIN 
    UPDATE tbUsers 
    SET 
    column = INSERTED.column, 
    … 
    FROM INSERTED 
    WHERE INSERTED.key = tbUsers.key 
    AND INSERTED.IsDeleted = 0 
    ; 
    DELETE FROM tbUsers 
    FROM INSERTED 
    WHERE INSERTED.key = tbUsers.key 
    AND INSERTED.IsDeleted = 1 
    ; 
    INSERT INTO tbDeletedUsers (columns) 
    SELECT columns 
    FROM INSERTED 
    WHERE IsDeleted = 1 
    ; 
END 
+1

Actualizaciones (columnName) no existe en SQL Server. En su lugar, use COLUMNS_UPDATED (columnName). http://msdn.microsoft.com/en-us/library/ms186329.aspx –

+1

Gracias por el comentario. Tiene razón, no hay función UPDATES() en SQL Server, ni UPDATED(), como escribí inicialmente. En realidad se llama [UPDATE()] (http://msdn.microsoft.com/en-us/library/ms187326.aspx). Editando mi respuesta y gracias de nuevo por llamar mi atención sobre mi error. –

+0

Y parece que también está equivocado, porque COLUMNS_UPDATED() no acepta un parámetro. Devuelve una máscara de bits que refleja todas las columnas afectadas por la instrucción que invoca el desencadenador. Nunca he usado esa función, aunque, según el manual, creo que tengo una idea aproximada de cómo usarla. –

Cuestiones relacionadas