多行触发器
我编写了一个触发器来记录对表的更改,当然直到之后我才意识到这一次只能对一条记录起作用。现在我正在尝试更新它以允许批量更新,但我不知道如何执行此操作。
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 时忽略它?
谢谢
I have written a trigger to log changes to a table and I of course didn't realize until after that this only works on one record at a time. Now I am trying to update it to allow for bulk updates and I cannot figure out how to do this.
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
Can anyone offer up any help on how to fix this to work with multiple rows? I attempted the following by adding the SELECT 1 FROM INSERTED
but I still get a subquery error message.
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
I have searched online but obviously I am still missing the correct way to do this. Any help would be greatly appreciated.
EDIT
I spoke with the business owners of this process and they want to ignore the updates on multiple rows. Is there a way to add an IF around the entire trigger to ignore it if the records are more than 0?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信您的条件检查可以最小化为 CASE 语句。似乎您可以最小化整个触发器,因为
我没有时间确保语法是否完美,但如果您遇到一些问题,我可以提供帮助。
为了响应您的编辑,可以使用类似的方法轻松完成
I believe your conditional checks can be minimized to CASE statements. It seems like you could minimize the entire trigger to
I didn't have time to make sure the syntax is perfect, but if you have some problems with it I can assist.
In response to your EDIT, that's done pretty easily with something like