2010-01-29 65 views
27

如果有:IF UPDATE()在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 ...所以我担心在这种情况下如果我想要做什么像这样添加条件?

回答

39

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

UPDATE table SET col = col 

这是一个更新。

UPDATE table SET col = 99 

当col已经有值99也是更新。

+11

请注意,在INSERT上,对于ALL列,UPDATED()函数返回1。当然。 – ErikE 2012-07-27 23:57:34

+1

并删除? – Rory 2015-03-24 17:12:53

+4

结果对于DELETE,UPDATE()函数不返回true。 http://stackoverflow.com/questions/29286034 – Rory 2015-03-26 18:22:52

10

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

+0

其实,我想要这个检查,以便执行不会更进一步,如果没有更新 – 2010-01-29 21:27:32

+0

肯定 - 您使用带有插入和删除表的if语句来比较原始值和新值 - 如果字段已更改,做你的事情 - 如果没有,请不要 – Ray 2010-01-29 22:44:53

2

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

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; 
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 

注意这个特殊的触发假设你的源表(一个触发扳机)和历史表具有相同的列布局。

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

这为我工作

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 

.....

+2

这是不安全的,因为插入和删除可以包含多个记录,如果UPDATE语句应用于多个记录。 – PapillonUK 2016-09-10 15:01:37