当前位置:  开发笔记 > 数据库 > 正文

仅在SQL Server中满足条件时才触发

如何解决《仅在SQLServer中满足条件时才触发》经验,为你挑选了4个好方法。

我希望这对任何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?我知道我接受了答案,但我想知道我自己的教育.



1> Joel Coehoor..:

鉴于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


使用此触发器,您只需处理一行.如果有人一次插入/更新2行或更多行,会发生什么?数据将是错误的.
_也是一个通配符,所以LIKE'NoHist_%'也会匹配'NoHistX'

2> Matty..:

这个怎么样?

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



3> HLGEM..:

您的where子句应该有效。我茫然为什么没有。让我告诉您我将如何解决where子句的问题,因为它可能对您将来有所帮助。

创建触发器时,首先从查询窗口开始,创建一个临时表,该临时表称为#inserted(和/或#deleted),并包含该表的所有列。然后我用典型值填充它(总是有多个记录,并且尝试在值中打测试用例)

然后,我编写触发器逻辑,然后进行测试,而无需实际将其放入触发器中。在您的where子句未按预期执行的情况下,我可以通过注释掉插入内容以查看select返回的内容来轻松进行测试。这样一来,我便可以很容易地看到问题所在。我向您保证,如果正确编写了clas,触发器在触发器中的作用。

一旦我知道代码在所有情况下都能正常工作,我就将#inserted替换为insert并在其周围添加创建触发器代码,然后瞧瞧,这是经过测试的触发器。

正如我在评论中所说,我担心您选择的解决方案在多记录插入或更新中无法正常工作。应该始终将触发器编写为考虑到这一点,因为您无法预测它们是否以及何时发生(并且最终确实会在每个表中发生)。



4> Cade Roux..:

这个_角色也是一个通配符,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

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有