我有一个触发器,仅在管理器更新时记录。我需要更改它,以便它为每个更新的字段插入一条记录。
例如此语句将在表 test_UpdateLog 中插入 3 条记录: 更新测试集经理='A',位置='B',部门='D';
更改触发器 [dbo].[TR_test_UpdateLog]
ON [dbo]。[测试]
更新后
AS
开始
INSERT INTO dbo.test_UpdateLog(TableName,PrimaryKeyValue,ColumnName,OldValue,NewValue,UpdatedBy)
SELECT 'test',i.Email,'Manager', d.Manager, i.Manager,USER_NAME()
FROM Inserted i
INNER JOIN Deleted d ON i.Email = d.Email
WHERE d.Manager <> i.Manager
结束;
一种方法就是一直存储所有更改......这在我的经验中非常典型。
然后,您可以查询您感兴趣的特定更改 - 请参阅本示例中的最后一个查询,其中我仅查询管理器中的更改。
CREATE TABLE dbo.Manager (
Id INT,
Email VARCHAR(50),
Manager VARCHAR(50),
[Location] VARCHAR(50),
PRIMARY KEY (Id))
CREATE TABLE dbo.Audit_Manager (
AuditAction CHAR(1),
AuditActionDateTime DATETIME,
AuditActionBy VARCHAR(50),
Id INT,
Email VARCHAR(50),
Manager VARCHAR(50),
[Location] VARCHAR(50))
GO
CREATE OR ALTER TRIGGER Manager_AfterUpdate ON dbo.Manager
FOR UPDATE
AS
BEGIN
INSERT INTO dbo.Audit_Manager (
AuditAction,
AuditActionDateTime,
AuditActionBy, Id,
Email,
Manager,
[Location])
SELECT
'I',
GETDATE(),
USER_NAME(),
Deleted.Id,
Deleted.Email,
Deleted.Manager,
Deleted.[Location]
FROM
Deleted
END
GO
CREATE OR ALTER TRIGGER Manager_AfterDelete ON dbo.Manager
FOR DELETE
AS
BEGIN
INSERT INTO dbo.Audit_Manager (
AuditAction,
AuditActionDateTime,
AuditActionBy,
Id,
Email,
Manager,
[Location])
SELECT
'D',
GETDATE(),
USER_NAME(),
Deleted.Id,
Deleted.Email,
Deleted.Manager,
Deleted.[Location]
FROM
Deleted
END
GO
-- Test Runner
INSERT INTO dbo.Manager (Id, Email, Manager, [Location])
VALUES
(1, '[email protected]', 'John', 'X'),
(2, '[email protected]', 'Paul', 'X')
WAITFOR DELAY '00:00:01'
UPDATE dbo.Manager SET Email = '[email protected]' WHERE Id = 1
WAITFOR DELAY '00:00:01'
UPDATE dbo.Manager SET Email = '[email protected]' WHERE Id = 1
WAITFOR DELAY '00:00:01'
UPDATE dbo.Manager SET Manager = 'Mary' WHERE Id = 1
WAITFOR DELAY '00:00:01'
UPDATE dbo.Manager SET [Location] = 'Y' WHERE Id = 1
WAITFOR DELAY '00:00:01'
UPDATE dbo.Manager SET Manager = 'Jane' WHERE Id = 1
-- ---------------------------------------------------
-- View changes (each row is compared to the next row)
-- ---------------------------------------------------
;WITH delta AS (
SELECT
AuditAction,
AuditActionDateTime,
AuditActionBy,
Id,
Email,
Manager,
[Location]
FROM dbo.Audit_Manager m
UNION ALL
SELECT
NULL AS AuditAction,
NULL AS AuditActionDateTime,
NULL AS AuditActionBy,
Id,
Email,
Manager,
[Location]
FROM dbo.Manager m
)
SELECT *
FROM delta
ORDER BY
Id,
IIF(AuditActionDateTime IS NULL, 0, 1),
AuditActionDateTime DESC
-- --------------------------------------------
-- View a particular change (change of manager)
-- --------------------------------------------
;WITH delta AS (
SELECT
AuditAction,
AuditActionDateTime,
AuditActionBy,
Id,
Email,
Manager,
[Location]
FROM dbo.Audit_Manager m
UNION ALL
SELECT
NULL AS AuditAction,
NULL AS AuditActionDateTime,
NULL AS AuditActionBy,
Id,
Email,
Manager,
[Location]
FROM dbo.Manager m
),
delta_ordered AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY AuditActionDateTime DESC) AS RN
FROM delta
)
SELECT t1.AuditAction, t1.AuditActionDateTime, t1.AuditActionBy, t1.Id, t1.Manager AS Manager_Was, t2.Manager AS Manager_Is
FROM delta_ordered t1
INNER JOIN delta_ordered t2
ON t1.Id = t2.Id
AND t1.RN = t2.RN-1
AND t1.Manager <> t2.Manager
ORDER BY
t1.Id,
t1.RN