I implementado recientemente una solución muy similar a este y tuvo que trabajar a través de una serie de obstáculos, así que dejo la solución aquí con la esperanza de que le ayudará.
Lo que quería hacer era tener una columna RecordCreated y LastModified que fuera administrada por la base de datos en lugar del agente de usuario. En este caso, RecordCreated sería el momento de la fecha en que se insertó por primera vez, y LastModified sería la última vez que se actualizó la fila. También quería evitar que el usuario modifique estas columnas directamente. Esto es lo que hice:
añadido las dos columnas a mi mesa como columnas SMALLDATETIME anulables:
RecordCreated SMALLDATETIME,
LastModified SMALLDATETIME
creado un después del disparo de la mesa:
CREATE TRIGGER dbo.WidgetProductionTrigger ON dbo.WidgetProduction AFTER INSERT, UPDATE AS BEGIN
El gatillo primero comprueba si el usuario intenté insertar/modificar los valores de mis columnas. Me detectado un problema con la función Update() siempre devuelve true, por lo que se requería un poco de lógica adicional:
DECLARE @RecordCreated SMALLDATETIME;
SELECT @RecordCreated = RecordCreated FROM INSERTED;
IF UPDATE(RecordCreated) AND NOT @RecordCreated IS NULL BEGIN
RAISERROR('RecordCreated is not user maintainable.', 16, 1);
ROLLBACK TRANSACTION;
RETURN;
END;
DECLARE @LastModified SMALLDATETIME;
SELECT @LastModified = LastModified FROM INSERTED;
IF UPDATE(LastModified) AND NOT @LastModified IS NULL BEGIN
RAISERROR('LastModified is not user maintainable.', 16, 1);
ROLLBACK TRANSACTION;
RETURN;
END;
A continuación, tiene lógica para añadir los valores requeridos para las columnas después de cada inserción o actualización. Puedo comprobar para ver si el registro está siendo insertado o actualizado y ejecutar la lógica apropiada:
IF EXISTS (SELECT * FROM DELETED) BEGIN
UPDATE dbo.WidgetProduction SET
LastModified = CAST(GETDATE() AS SMALLDATETIME)
WHERE ProductionRecordID IN (SELECT ProductionRecordID FROM INSERTED);
END ELSE BEGIN
UPDATE dbo.WidgetProduction SET
RecordCreated = CAST(GETDATE() AS SMALLDATETIME),
LastModified = CAST(GETDATE() AS SMALLDATETIME)
WHERE ProductionRecordID IN (SELECT ProductionRecordID FROM INSERTED);
END;
Esta solución funciona exactamente como se esperaba.
Tenía la esperanza de evitar la necesidad de reversiones y sólo tienen de modo que no se puede escribir a. Me gusta tu respuesta. La otra forma de hacerlo, es hacer un en lugar de desencadenar como se muestra a continuación, pero eso debe mantenerse con la tabla. No estoy seguro de cuál sería mejor. – GordyII