【发布时间】:2010-10-30 17:22:52
【问题描述】:
我有一个触发器,可以插入和更新视图。我需要找到正在修改的列并将值放入正确的表中。
INSERT INTO TempTableAttr_Lot(ID, [% Num]) VALUES(3, 24.0)
我试图弄清楚如何在我的触发器中获取 ID 和 [% Num] 列的值。问题是在插入或更新中可以设置 32 个不同的列,所以我想循环查看该列是否在“插入”表中。
一个问题是,如果我使用 exec 或 execute 来构建动态查询,insert 不在此范围内。
视图是动态的,如果添加了属性,那么视图会由存储过程重新生成,所以我不能假设视图中的列名在任何给定时间都可以增长和缩小。
理想情况下我想做SET @Value = (SELECT i.[@Name] FROM inserted i) 但是@Name 不是列名,而是我触发器中的一个变量,所以当我尝试时
DECLARE @ValueTable TABLE ( value sql_variant)
INSERT INTO @ValueTable EXECUTE('SELECT i.[' + @Name + '] FROM inserted i')
SET @Value = CONVERT(nvarchar(128), (SELECT DISTINCT * FROM @ValueTable))
这不起作用,因为插入的似乎不在范围内。
对于第一个循环 @Name = 'ID' 和第二个循环它将是 'Col2' 没有插入,所以 @Value 的值应该为空,我继续循环遍历可能的列名,直到我完成,触发器被处理。
我称之为触发器,它定义为:
CREATE TRIGGER TempTableAttr_LotTrigger
ON TempTableAttr_Lot
INSTEAD OF UPDATE, INSERT
我目前正在使用 INSERT 命令进行测试。我意识到在进行更新时我可能需要查看“已删除”表。
更新:我假设目前只插入一行,以进行测试,看看如何让它工作。这是一个实体-属性-值数据库,但我有一个使它看起来有关系的视图。使用集成服务时,更新正在进行时,对视图的任何插入或更新都会调用触发器。我只是想了解如何获取我需要的信息,以便使用正确的值更新正确的表。
【问题讨论】:
-
这些列值的真正去向是什么?这不是@ValueTable,因为 A) 表变量在过程结束时消失,B) 它不能识别源列,因此您无法将 ID 与其中的 [% Num] 区分开来。另外,您似乎假设一次只插入一行,这是真的吗?
-
您的触发器永远不能假定只插入一个值。这种方式会导致数据完整性问题。
-
@HLGEM - 实际上我的触发器工作得很好,当我完成时,有多个插入,因为我只是循环遍历,但我从一个插入的简单案例开始以限制并发症。
-
在触发器中循环是个坏主意,如果批量插入 100,000 条记录会怎样?
-
@HLGEM - 出于必要风险的应用程序的目的,重新生成所有已更改表的视图。
标签: sql-server sql-server-2008 triggers dynamic-sql