IF UPDATE()在SQL服务器上触发。

问题描述 投票:32回答:8

如果在表上的SQL服务器触发器中有:

IF UPDATE (col1)

...在表的SQL服务器触发器中,是否只有在col1被改变或更新时才返回true?

我有一个常规的更新查询,比如

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

现在我担心的是,如果 "col1 "之前是'x',那么我们再把它更新为'x',就会出现这样的情况 IF UPDATE ("col1") 触发器是否返回True?

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

sql sql-server sql-server-2005 triggers
8个回答
51
投票

如果一列被更新,它将返回true。更新意味着查询已经将列的值SET了。之前的值是否与新的值相同在很大程度上是不相关的。

UPDATE table SET col = col

它是一个更新。

UPDATE table SET col = 99

当列的值已经是99时,也是一个更新。


11
投票

在触发器中,你可以访问两个内部表,这可能会有帮助。插入 "表包括每条受影响的行的新版本,"删除 "表包括每条行的原始版本。你可以比较这两个表中的值,看看你的字段值是否真的被改变了。


2
投票

你要做的是检查插入表和删除表中的不同值,而不是使用update()(别忘了考虑空值)。或者你可以停止做不需要的更新。


2
投票

这里有一个快速的方法,在决定运行触发器的内容之前,扫描行,看看是否有任何列发生了变化。例如,当你想写一条历史记录,但如果没有任何变化,你就不想写了,这就很有用。

我们在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

请注意,这个特殊的触发器假设你的源表(触发器的表)和历史表有相同的列布局。


1
投票

为了快捷处理 "没有实际更新 "的情况,你还需要在开始时检查你的查询是否影响了任何记录。

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

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

0
投票
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)

-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

.....

© www.soinside.com 2019 - 2024. All rights reserved.