IF服务器中的UPDATE()触发器

时间:2010-01-29 18:42:08

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

如果有:

IF UPDATE (col1)

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

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

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

现在关注的是,如果“col1”先前为“x”,那么我们再次将其更新为“x” 会IF UPDATE ("col1")触发返回True还是不?

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

8 个答案:

答案 0 :(得分:46)

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

UPDATE table SET col = col

这是一次更新。

UPDATE table SET col = 99

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

答案 1 :(得分:10)

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

答案 2 :(得分:2)

您所做的是检查inserted和deleted表中的不同值,而不是使用updated()(不要忘记考虑空值)。或者你可以停止做不需要的更新。

答案 3 :(得分: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

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

答案 4 :(得分: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;

答案 5 :(得分: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

答案 6 :(得分: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)

答案 7 :(得分:-1)

这对我有用

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

.....