无光标触发批量更新
我在 SQL Server 2005 中有一个触发器,用于跟踪特定字段的审核更改。我们在单独的表中跟踪变化。此触发器按单个记录条目的预期工作,这就是它的预期,但现在他们希望通过批量更新跟踪对列所做的更改。
当前触发器:
CREATE TRIGGER [dbo].[trg_LogChanges]
ON [dbo].[Test]
FOR UPDATE
AS
DECLARE @TableName VARCHAR(100) ,
@UpdatedDate smalldatetime ,
@UpdatedBy uniqueidentifier
SELECT @TableName = 'dbo.Test'
IF(SELECT COUNT(*) FROM INSERTED) = 1
BEGIN
IF(SELECT LastModifiedDate FROM INSERTED) Is Null
SET @UpdatedDate = getdate()
ELSE
SET @UpdatedDate = (SELECT LastModifiedDate FROM INSERTED)
IF(SELECT LastModifiedBy FROM INSERTED) Is Null
SET @UpdatedBy = '11111111-1111-1111-1111-111111111111'
ELSE
SET @UpdatedBy = (SELECT LastModifiedBy FROM INSERTED)
IF UPDATE (ActDate)
BEGIN
INSERT INTO dbo.LogChanges
(
ChangeType
, TableName
, RecordGuid
, FieldName
, OldValue
, NewValue
, UpdatedBy
, UpdatedDate
)
SELECT
'U'
, @TableName
, d.Guid
, 'ActDate'
, d.ActDate
, i.ActDate
, @UpdatedBy
, @UpdatedDate
FROM INSERTED i
INNER JOIN DELETED d
on i.Guid = d.Guid
WHERE
(d.ActDate IS NULL AND i.ActDate IS NOT NULL)
OR (d.ActDate IS NOT NULL AND i.ActDate IS NULL)
OR (d.ActDate <> i.ActDate)
END
-- this keeps going for each field that we need to get the Audit Trail on
END
ELSE
BEGIN
-- now I need to track for multiple records
-- I tried changing the WHERE clause above to see if it would work for bulk updates
INSERT INTO...
SELECT...
WHERE
(
(d.ActDate IS NULL AND i.ActDate IS NOT NULL)
OR (d.ActDate IS NOT NULL AND i.ActDate IS NULL)
OR (d.ActDate <> i.ActDate)
)
AND d.ActDate IN (SELECT d.ActDate FROM DELETED d)
END
此代码不适用于多个记录,它会引发错误:
Subquery returned more than 1 value. This is not permitted when the subquery
follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
如何更改当前触发器以进行批量更新。我必须使用光标来执行此操作吗?如果是这样,那么有人可以提供一些示例代码吗?
I have a trigger in SQL Server 2005 that is used to track audit changes on specific fields. We track the changes in a separate table. This trigger works as expected for the single record entries which is how it was intended but now they want to track changes made to the column via a bulk update.
Current trigger:
CREATE TRIGGER [dbo].[trg_LogChanges]
ON [dbo].[Test]
FOR UPDATE
AS
DECLARE @TableName VARCHAR(100) ,
@UpdatedDate smalldatetime ,
@UpdatedBy uniqueidentifier
SELECT @TableName = 'dbo.Test'
IF(SELECT COUNT(*) FROM INSERTED) = 1
BEGIN
IF(SELECT LastModifiedDate FROM INSERTED) Is Null
SET @UpdatedDate = getdate()
ELSE
SET @UpdatedDate = (SELECT LastModifiedDate FROM INSERTED)
IF(SELECT LastModifiedBy FROM INSERTED) Is Null
SET @UpdatedBy = '11111111-1111-1111-1111-111111111111'
ELSE
SET @UpdatedBy = (SELECT LastModifiedBy FROM INSERTED)
IF UPDATE (ActDate)
BEGIN
INSERT INTO dbo.LogChanges
(
ChangeType
, TableName
, RecordGuid
, FieldName
, OldValue
, NewValue
, UpdatedBy
, UpdatedDate
)
SELECT
'U'
, @TableName
, d.Guid
, 'ActDate'
, d.ActDate
, i.ActDate
, @UpdatedBy
, @UpdatedDate
FROM INSERTED i
INNER JOIN DELETED d
on i.Guid = d.Guid
WHERE
(d.ActDate IS NULL AND i.ActDate IS NOT NULL)
OR (d.ActDate IS NOT NULL AND i.ActDate IS NULL)
OR (d.ActDate <> i.ActDate)
END
-- this keeps going for each field that we need to get the Audit Trail on
END
ELSE
BEGIN
-- now I need to track for multiple records
-- I tried changing the WHERE clause above to see if it would work for bulk updates
INSERT INTO...
SELECT...
WHERE
(
(d.ActDate IS NULL AND i.ActDate IS NOT NULL)
OR (d.ActDate IS NOT NULL AND i.ActDate IS NULL)
OR (d.ActDate <> i.ActDate)
)
AND d.ActDate IN (SELECT d.ActDate FROM DELETED d)
END
This code doesn't work for multiple records it throws an error:
Subquery returned more than 1 value. This is not permitted when the subquery
follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
How can I alter my current trigger to work for a bulk update. Do I have to use a cursor to do it? If so, then can someone offer some sample code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当有多个记录时,如何设置@UpdatedDate和@UpdatedBy?我怀疑你正在做类似的事情,这就是你为一张记录所做的事情。
如果 INSERTED 中有多于一行,则 ELSE 下的 SET 将导致错误。
试试这个
这应该适用于任意数量的记录,包括一条记录。请注意,我没有检查
UPDATE(ActDate)
。如果 ActDate 没有更改,则不会返回任何记录。How are you setting @UpdatedDate and @UpdatedBy when there is more than one record? I suspect you are doing something like this, which is what you are doing for one record.
The SET under ELSE will cause the error if there is more than one row in INSERTED.
Try this instead
This should work for any number of records, including just one. Note that I am not checking
UPDATE(ActDate)
. No records will be returned if ActDate did not change.