Недавно я реализовал очень похожее решение для этого, и мне пришлось преодолеть ряд препятствий, поэтому я публикую здесь решение, надеясь, что оно поможет.
То, что я хотел сделать, это иметь RecordCreatedи столбец LastModified, который управлялся базой данных, а не пользовательским агентом.В этом случае RecordCreated будет датой и временем, когда строка была впервые вставлена, а LastModified будет последним обновлением строки.Я также хотел запретить пользователю изменять эти столбцы напрямую.Вот что я сделал:
Добавил два столбца в мою таблицу как обнуляемые столбцы SMALLDATETIME:
RecordCreated SMALLDATETIME,
LastModified SMALLDATETIME
Создал триггер AFTER для таблицы:
CREATE TRIGGER dbo.WidgetProductionTrigger ON dbo.WidgetProduction AFTER INSERT, UPDATE AS BEGIN
инициировать сначала проверяет, пытался ли пользователь вставить / изменить значения моих столбцов.Я столкнулся с проблемой с функцией UPDATE (), всегда возвращающей true, поэтому потребовалась небольшая дополнительная логика:
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;
Далее, у меня есть логика для добавления необходимых значений в столбцы после каждой вставки или обновления.Я проверяю, вставляется или обновляется запись, и выполняю соответствующую логику:
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;
Это решение работает точно так, как ожидалось.