我希望这对任何SQL人来说都是一个简单的问题...
我们有一个保存系统配置数据的表,它通过触发器绑定到历史表,因此我们可以跟踪谁更改了什么,何时更改.
我需要在此表中添加另一个值,但它会经常从代码中更改,并且要求我们不跟踪它的历史记录(我们不希望用数千个阻塞它的表)每天更新.
目前,我们的触发器有点像这样......
CREATE TRIGGER [dbo].[SystemParameterInsertUpdate] ON [dbo].[SystemParameter] FOR INSERT, UPDATE AS BEGIN SET NOCOUNT ON INSERT INTO SystemParameterHistory ( Attribute, ParameterValue, ParameterDescription, ChangeDate ) SELECT Attribute, ParameterValue, ParameterDescription, ChangeDate FROM Inserted AS I END
如果Attribute colum值以特定字符串为前缀(例如"NoHist_"),我希望能够添加一些逻辑来阻止它创建记录
鉴于我几乎没有使用触发器的经验,我想知道如何最好地实现这个...我已经尝试过如下的where子句
where I.Attribute NOT LIKE 'NoHist_%'
但它似乎没有用.该值仍会复制到历史记录表中.
您可以提供的任何帮助将不胜感激.
好的 - 正如Cade Roux预测的那样,这次失败引起了多次更新.我将不得不对此采取新方法.有没有人有任何其他建议,拜托?
伙计们 - 请在这里教育我......为什么LEFT()在这种情况下会更喜欢LIKE?我知道我接受了答案,但我想知道我自己的教育.
鉴于WHERE子句不起作用,可能会:
CREATE TRIGGER [dbo].[SystemParameterInsertUpdate] ON [dbo].[SystemParameter] FOR INSERT, UPDATE AS BEGIN SET NOCOUNT ON If (SELECT Attribute FROM INSERTED) LIKE 'NoHist_%' Begin Return End INSERT INTO SystemParameterHistory ( Attribute, ParameterValue, ParameterDescription, ChangeDate ) SELECT Attribute, ParameterValue, ParameterDescription, ChangeDate FROM Inserted AS I END
这个怎么样?
CREATE TRIGGER [dbo].[SystemParameterInsertUpdate] ON [dbo].[SystemParameter] FOR INSERT, UPDATE AS BEGIN SET NOCOUNT ON IF (LEFT((SELECT Attribute FROM INSERTED), 7) <> 'NoHist_') BEGIN INSERT INTO SystemParameterHistory ( Attribute, ParameterValue, ParameterDescription, ChangeDate ) SELECT Attribute, ParameterValue, ParameterDescription, ChangeDate FROM Inserted AS I END END
您的where子句应该有效。我茫然为什么没有。让我告诉您我将如何解决where子句的问题,因为它可能对您将来有所帮助。
创建触发器时,首先从查询窗口开始,创建一个临时表,该临时表称为#inserted(和/或#deleted),并包含该表的所有列。然后我用典型值填充它(总是有多个记录,并且尝试在值中打测试用例)
然后,我编写触发器逻辑,然后进行测试,而无需实际将其放入触发器中。在您的where子句未按预期执行的情况下,我可以通过注释掉插入内容以查看select返回的内容来轻松进行测试。这样一来,我便可以很容易地看到问题所在。我向您保证,如果正确编写了clas,触发器在触发器中的作用。
一旦我知道代码在所有情况下都能正常工作,我就将#inserted替换为insert并在其周围添加创建触发器代码,然后瞧瞧,这是经过测试的触发器。
正如我在评论中所说,我担心您选择的解决方案在多记录插入或更新中无法正常工作。应该始终将触发器编写为考虑到这一点,因为您无法预测它们是否以及何时发生(并且最终确实会在每个表中发生)。
这个_
角色也是一个通配符,BTW,但我不确定为什么这不适合你:
CREATE TRIGGER [dbo].[SystemParameterInsertUpdate] ON [dbo].[SystemParameter] FOR INSERT, UPDATE AS BEGIN SET NOCOUNT ON INSERT INTO SystemParameterHistory ( Attribute, ParameterValue, ParameterDescription, ChangeDate ) SELECT I.Attribute, I.ParameterValue, I.ParameterDescription, I.ChangeDate FROM Inserted AS I WHERE I.Attribute NOT LIKE 'NoHist[_]%' END