【问题标题】:IF UPDATE() in SQL server triggerSQL 服务器触发器中的 IF UPDATE()
【发布时间】:2011-01-10 23:30:46
【问题描述】:

如果有:

IF UPDATE (col1)

...在表的 SQL Server 触发器中,是否仅当 col1 已更改或更新时才返回 true?

我有一个定期更新查询,例如

UPDATE table-name 
   SET col1 = 'x', 
       col2 =  'y' 
 WHERE id = 999

现在我担心的是,如果“col1”之前是“x”,那么我们再次将其更新为“x” IF UPDATE ("col1") trigger 会返回 True 吗?

我正面临这个问题,因为我的保存查询对于所有列都是通用的,但是当我添加此条件时,即使它没有更改,它也会返回 True...所以我担心如果我想添加在这种情况下该怎么做这样的情况?

【问题讨论】:

    标签: sql sql-server sql-server-2005 triggers


    【解决方案1】:

    触发器

    CREATE TRIGGER boo  ON status2 FOR UPDATE AS 
    IF UPDATE (id)
    BEGIN
       SELECT 'DETECT'; 
    END;
    

    用法

    UPDATE status2 SET name = 'K' WHERE name= 'T' --no action 
    UPDATE status2 SET name = 'T' ,id= 8 WHERE name= 'K' --detect
    

    【讨论】:

      【解决方案2】:

      这对我有用

      DECLARE @LongDescDirty bit = 0
      
      Declare @old varchar(4000) = (SELECT LongDescription from deleted)
      Declare @new varchar(4000) = (SELECT LongDescription from inserted)
      
      if (@old <> @new)
          BEGIN
              SET @LongDescDirty = 1
          END
      
      Update table
        Set LongDescUpdated = @LongDescUpdated
      

      .....

      【讨论】:

      • 这是不安全的,因为如果 UPDATE 语句应用于多条记录,则插入和删除可以包含多条记录。
      【解决方案3】:
      SET NOCOUNT ON;
      
          declare @countTemp int
          select @countTemp = Count (*) from (
          select City,PostCode,Street,CountryId,Address1 from Deleted
          union
          select City,PostCode,Street,CountryId,Address1 from Inserted
          ) tempTable
      
          IF ( @countTemp > 1 )
      
      Begin
      
      -- Your Code goes Here
      End
      
      -- if any of these  "City,PostCode,Street,CountryId,Address1" got updated then trigger
      
      -- will  work in " IF ( @countTemp > 1 ) " Code)
      

      【讨论】:

        【解决方案4】:

        这是一种在决定运行触发器的内容之前扫描行以查看是否有任何列发生更改的快速方法。例如,当您想写入历史记录时,这可能很有用,但如果没有真正改变,您就不想这样做。

        我们在 ETL 导入过程中一直使用它,我们可能会重新导入数据,但如果源文件中没有真正更改,我们不想创建新的历史记录。

        CREATE TRIGGER [dbo].[TR_my_table_create_history]
        ON [dbo].[my_table] FOR UPDATE AS
        
        BEGIN
        
            --
            -- Insert the old data row if any column data changed
            --
            INSERT INTO [my_table_history]
            SELECT  d.*
            FROM    deleted d
            INNER JOIN inserted i ON i.[id] = d.[id]
            --
            -- Use INTERSECT to see if anything REALLY changed
            --
            WHERE   NOT EXISTS( SELECT i.* INTERSECT SELECT d.* )
        
        END
        

        请注意,此特定触发器假定您的源表(触发触发器的那个)和历史表具有相同的列布局。

        【讨论】:

          【解决方案5】:

          要简化“没有实际更新”的情况,您还需要在开始时检查您的查询是否影响了任何行:

          set nocount on; -- this must be the first statement!
          if not exists (select 1 from inserted) and not exists (select 1 from deleted)
            return;
          

          【讨论】:

            【解决方案6】:

            您要做的是检查插入和删除表中的不同值,而不是使用 updated() (不要忘记考虑空值)。或者您可以停止进行不必要的更新。

            【讨论】:

              【解决方案7】:

              如果列已更新,则返回 true。更新意味着查询已设置列的值。以前的值是否与新值相同在很大程度上无关紧要。

              UPDATE table SET col = col
              

              这是一个更新。

              UPDATE table SET col = 99
              

              当 col 已经有值 99 时,它也是一个更新。

              【讨论】:

              • 请注意,在 INSERT 中,UPDATED() 函数为所有列返回 1。当然。
              • 原来 UPDATE() 函数不会为删除返回 true。 stackoverflow.com/questions/29286034
              • 我想知道用户是否指的是列从一个值更改为不同值的位置,而不仅仅是用相同的值覆盖该值。
              【解决方案8】:

              在触发器中,您可以访问两个可能有帮助的内部表。 “插入”表包括每个受影响行的新版本,“删除”表包括每行的原始版本。您可以比较这些表中的值,以查看您的字段值是否实际发生了更改。

              【讨论】:

              • 其实,我想要这个检查,以便在没有更新的情况下执行不会进一步
              • 当然 - 您使用 if 语句与插入和删除的表来比较原始值和新值 - 如果字段已更改,请执行您的操作 - 如果没有,请不要
              猜你喜欢
              • 2021-11-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-04-07
              • 1970-01-01
              相关资源
              最近更新 更多