我有一个任务 - 创建更新触发器,它可以处理实际的表数据更改(不只是使用相同的值进行更新)。为此,我创建了复制表,然后开始将更新的行与旧的复制行进行比较。当触发器完成时,需要实现副本:
UPDATE CopyTable SET
id = s.id,
-- many, many fields
FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED)
AND CopyTable.id = s.id;
我不喜欢在触发器中使用这个丑陋的代码,所以我将其解压缩到存储过程:
CREATE PROCEDURE UpdateCopy AS
BEGIN
UPDATE CopyTable SET
id = s.id,
-- many, many fields
FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED)
AND CopyTable.id = s.id;
END
结果是 - 无效的对象名称“INSERTED”。我该如何解决这个问题?
此致
答案 0 :(得分:4)
将代码保留在触发器中。 INSERTED
是仅在触发器代码中可用的伪表。 不尝试传递此伪表值,它可能包含大量条目。
这是T-SQL,一种声明性数据访问语言。它不是您的普通程序编程语言。像“代码重用”这样的常识不适用于SQL,它只会导致性能问题。将代码保留在它所属的触发器中。为了便于重新分解,通过一些代码生成工具生成触发器,以便您可以轻松地重构触发器。
答案 1 :(得分:2)
问题是INSERTED仅在触发期间可用
- 触发更改以构建ID的列表
DECLARE @idStack VARCHAR(max)
SET @idStack=','
SELECT @idStack=@idStack+ltrim(str(id))+',' FROM INSERTED
- 触发更改以调用存储过程
EXEC updateCopy(@idStack)
- 以逗号分隔的ID列表
的过程CREATE PROCEDURE UpdateCopy(@IDLIST VARCHAR(max)) AS
BEGIN
UPDATE CopyTable SET
id = s.id,
-- many, many fields
FROM MainTable s WHERE charindex(','+ltrim(str(s.id))+',',@idList) > 0
AND CopyTable.id = s.id;
END
性能不会很好,但应该让你做你想做的事。
只需即时输入,但应运行正常
答案 2 :(得分:0)
真正的问题是“如何在存储过程中传递GUID数组?”或者,更广泛的,“如何在存储过程中传递数组?”。
以下是答案: