如果在表上的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......所以我关心的是,如果我想添加这样的条件,在这种情况下该怎么办?
如果一列被更新,它将返回true。更新意味着查询已经将列的值SET了。之前的值是否与新的值相同在很大程度上是不相关的。
UPDATE table SET col = col
它是一个更新。
UPDATE table SET col = 99
当列的值已经是99时,也是一个更新。
在触发器中,你可以访问两个内部表,这可能会有帮助。插入 "表包括每条受影响的行的新版本,"删除 "表包括每条行的原始版本。你可以比较这两个表中的值,看看你的字段值是否真的被改变了。
你要做的是检查插入表和删除表中的不同值,而不是使用update()(别忘了考虑空值)。或者你可以停止做不需要的更新。
这里有一个快速的方法,在决定运行触发器的内容之前,扫描行,看看是否有任何列发生了变化。例如,当你想写一条历史记录,但如果没有任何变化,你就不想写了,这就很有用。
我们在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
请注意,这个特殊的触发器假设你的源表(触发器的表)和历史表有相同的列布局。
为了快捷处理 "没有实际更新 "的情况,你还需要在开始时检查你的查询是否影响了任何记录。
set nocount on; -- this must be the first statement!
if not exists (select 1 from inserted) and not exists (select 1 from deleted)
return;
触发器:
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
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)
这对我很有效
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
.....