我已经写了一个触发器来记录对表的更改,我当然没有意识到,直到那之后,它一次只能在一条记录上运行。现在我正在尝试更新它以允许批量更新,我无法弄清楚如何执行此操作。
CREATE TRIGGER [DT].[trg_LogChanges]
ON [DT].[NewDetails]
FOR UPDATE
AS
DECLARE
@TableName VARCHAR(100) ,
@UpdatedDate smalldatetime ,
@UpdatedBy uniqueidentifier
SELECT @TableName = 'DT.NewDetails'
IF EXISTS (SELECT 1 FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid)
IF(SELECT ModifiedDate FROM INSERTED) Is Null
SET @UpdatedDate = getdate()
ELSE
SET @UpdatedDate = (SELECT ModifiedDate FROM INSERTED)
IF(SELECT ModifiedBy FROM INSERTED) Is Null
SET @UpdatedBy = '11111111-1111-1111-1111-111111111111'
ELSE
SET @UpdatedBy = (SELECT ModifiedBy FROM INSERTED)
IF UPDATE (StatusID)
BEGIN
INSERT INTO DT.LogChanges
(
ChangeType, TableName, RecordGuid, FieldName
, OldValue, NewValue, UpdatedBy, UpdatedDate
)
SELECT
'U', @TableName, d.Guid, 'StatusID'
, d.StatusID, i.StatusID, @UpdatedBy, @UpdatedDate
FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid
WHERE
(d.StatusID IS NULL AND i.StatusID IS NOT NULL)
OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL)
OR (d.StatusID <> i.StatusID)
END
任何人都可以提供有关如何修复此问题的任何帮助以使用多行吗?我通过添加SELECT 1 FROM INSERTED
尝试以下操作,但仍然会收到子查询错误消息。
CREATE TRIGGER [DT].[trg_LogChanges]
ON [DT].[NewDetails]
FOR UPDATE
AS
DECLARE
@TableName VARCHAR(100) ,
@UpdatedDate smalldatetime ,
@UpdatedBy uniqueidentifier
SELECT @TableName = 'DT.NewDetails'
IF EXISTS (SELECT 1 FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid)
IF(SELECT ModifiedDate FROM INSERTED) Is Null
SET @UpdatedDate = getdate()
ELSE
SET @UpdatedDate = (SELECT ModifiedDate FROM INSERTED)
IF(SELECT ModifiedBy FROM INSERTED) Is Null
SET @UpdatedBy = '11111111-1111-1111-1111-111111111111'
ELSE
SET @UpdatedBy = (SELECT ModifiedBy FROM INSERTED)
IF UPDATE (StatusID)
BEGIN
IF EXISTS (SELECT 1 FROM INSERTED i
INNER JOIN DELETED d
on i.Guid = d.Guid
WHERE
(d.StatusID IS NULL AND i.StatusID IS NOT NULL)
OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL)
OR (d.StatusID <> i.StatusID))
BEGIN
INSERT INTO DT.LogChanges
(
ChangeType, TableName, RecordGuid, FieldName
, OldValue, NewValue, UpdatedBy, UpdatedDate
)
SELECT
'U', @TableName, d.Guid, 'StatusID'
, d.StatusID, i.StatusID, @UpdatedBy, @UpdatedDate
FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid
WHERE
(d.StatusID IS NULL AND i.StatusID IS NOT NULL)
OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL)
OR (d.StatusID <> i.StatusID)
END
END
我在网上搜索过,但显然我仍然错过了正确的方法。任何帮助将不胜感激。
修改 我与此流程的业务所有者进行了交谈,他们希望忽略多行的更新。有没有办法在整个触发器周围添加IF,如果记录大于0,则忽略它?
由于
答案 0 :(得分:2)
我相信您的条件检查可以最小化到CASE语句。看起来你可以最小化整个触发器
INSERT INTO DT.LogChanges (ChangeType, TableName, RecordGuid, FieldName, OldValue, NewValue, UpdatedBy, UpdatedDate)
SELECT 'U', 'DT.NewDetails', d.Guid, 'StatusID', d.StatusID, i.StatusID,
CASE WHEN i.ModifiedBy IS NULL THEN GETDATE() ELSE i.ModifiedBy AS ModifiedBy,
CASE WHEN i.ModifiedDate IS NULL THEN '11111111-1111-1111-1111-111111111111' ELSE i.ModifiedDate AS ModifiedDate
FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid
WHERE (d.StatusID IS NULL AND i.StatusID IS NOT NULL)
OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL)
OR (d.StatusID <> i.StatusID)
我没有时间确保语法完美,但如果你遇到一些问题,我可以提供帮助。
为了回应你的编辑,用
之类的东西很容易做到IF (SELECT COUNT(*) FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid) = 1
BEGIN
PRINT 'Only one update record'
END