2010-06-30 124 views
2

我有一个触发器用于审计插入,更新和删除的行。我从触发器获取旧价值和新价值方面存在问题。触发器利用一个循环来插入以任何方式被改变的任何行的所有值(插入,更新,删除)。但是,我的代码没有返回值,而是将列名称作为值。SQL更新/删除触发器无法正常工作

这里是我的代码部分:

SELECT @COLNAME = NAME 
FROM SYSCOLUMNS 
WHERE COLID = @FIELD AND 
    ID = (SELECT ID FROM SYSOBJECTS WHERE NAME = 'FIN_HOTEL_DTL_TYPE') 
SELECT @OLDVAL = SUBSTRING(@COLNAME, 2, LEN(@COLNAME)) FROM DELETED 
SELECT @NEWVAL = SUBSTRING(@COLNAME, 2, LEN(@COLNAME)) FROM INSERTED 
SELECT @MODBY = MODIFIED_BY FROM INSERTED 
SELECT @MODDT = MODIFIED_DATETIME FROM INSERTED 

回答

3

T-SQL仅仅是一个不同的世界。

你的代码正在做你刚才告诉它做的事情。 @ColName不是对列对象的引用,而是一个包含已加载列名称的字符串值的变量。我建议你看一下example。如果你愿意的话,可以阅读整个内容,但如果你急着写下CREATE TRIGGER Audit这个短语。

另外,花时间用set based逻辑来做到这一点 - 就像例子中那样。通过利用T-SQL和逐行编码来释放债券,利用DBMS的能力和性能。不完全是。编码循环=糟糕的表现。如果需要,DBMS将在后台实现循环(或者希望)。

祝你好运!


我在前面试图找到这个链接。我相信Paul Nielsen的this posting非常接近你想要的。

+0

是的,我想到了@ColName。我正在使用这种类型的逻辑,因为有些表格有大量的列(遗留数据库,不幸的是我的选择),我不想编码每列。 – mattgcon 2010-06-30 18:46:38

+0

美丽的答案,特别是有关避免在循环中执行此操作的部分。我已经实现了类似的触发器,除了表现更好之外,它们更短,更简单,没有循环。 – TimothyAWiseman 2010-07-01 00:13:06

+0

谢谢你的帮助。我拿出了循环,并简单地单独引用列。 – mattgcon 2010-07-01 16:57:28