能否在SQL Server触发器中多次使用UPDATE()函数?
我正在尝试测试触发器中更新了哪些列。我知道可以像这样使用更新功能能否在SQL Server触发器中多次使用UPDATE()函数?,sql,sql-server,triggers,Sql,Sql Server,Triggers,我正在尝试测试触发器中更新了哪些列。我知道可以像这样使用更新功能 IF (UPDATE(Column1) OR UPDATE(Column2) OR UPDATE(Column3)) Do something... 但是我需要能够分别测试每一列,并且在以下方面没有取得任何成功 DECLARE TriggerCursor CURSOR READ_ONLY FOR SELECT SOPNUMBE, SOPTYPE, CMPNTSEQ, LNITMSEQ, ITE
IF (UPDATE(Column1) OR UPDATE(Column2) OR UPDATE(Column3))
Do something...
但是我需要能够分别测试每一列,并且在以下方面没有取得任何成功
DECLARE TriggerCursor CURSOR READ_ONLY FOR
SELECT
SOPNUMBE, SOPTYPE, CMPNTSEQ, LNITMSEQ, ITEMNMBR,
QUANTITY, UNITPRCE, PRSTADCD
FROM
inserted;
OPEN TriggerCursor;
FETCH NEXT FROM TriggerCursor INTO @sSOPNumber, @nSOPType, @nComponentSeq,
@nLineItemSeq, @sItemNumber, @cyQuantity,
@cyUnitPrice, @sShipToAddress;
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
IF UPDATE(QUANTITY)
BEGIN
SET @sAction = 'Changed Quantity from ' + RTRIM(CONVERT(CHAR,(select QUANTITY from deleted))) + ' to ' + RTRIM(CONVERT(CHAR, @cyQuantity));
END;
IF UPDATE(UNITPRCE)
BEGIN
IF LEN(@sAction) = ''
SET @sAction = 'Changed Unit Price from ' + RTRIM(CONVERT(CHAR,(select UNITPRCE from deleted))) + ' to ' + RTRIM(CONVERT(CHAR, @cyUnitPrice));
ELSE
SET @sAction = @sAction + 'and Unit Price from ' + RTRIM(CONVERT(CHAR,(select UNITPRCE from deleted))) + ' to ' + RTRIM(CONVERT(CHAR, @cyUnitPrice));
END;
IF UPDATE(PRSTADCD)
BEGIN
IF @sAction = ''
SET @sAction = 'Changed ShipTo Address from ' + RTRIM(CONVERT(CHAR,(select PRSTADCD from deleted))) + ' to ' + RTRIM(CONVERT(CHAR, @sShipToAddress));
ELSE
SET @sAction = @sAction + 'and ShipTo Address from ' + RTRIM(CONVERT(CHAR,(select PRSTADCD from deleted))) + ' to ' + RTRIM(CONVERT(CHAR, @sShipToAddress));
END;
EXEC NC_IDS_Insert_SOP_Audit_Record
@sSOPNumber, @nSOPType, @nComponentSeq,
@nLineItemSeq, @sUserId, @sAction, @dDate, @dTime;
END;
FETCH NEXT FROM TriggerCursor INTO @sSOPNumber, @nSOPType, @nComponentSeq, @nLineItemSeq, @sItemNumber, @cyQuantity, @cyUnitPrice, @sShipToAddress;
END;
CLOSE TriggerCursor;
DEALLOCATE TriggerCursor;
每次似乎只测试第1列时,忽略其他列,即使在更新行时所有三列都已更新
编辑:忘记提到更新发生在光标内,所以不确定这是否是导致我的问题的原因?当然可以。发件人:
返回一个布尔值,该值指示是否对表或视图的指定列进行了插入或更新尝试。UPDATE用于Transact-SQL插入或更新触发器主体内的任何位置,以测试触发器是否应执行某些操作
例如:
CREATE TABLE t(i INT, a INT, b INT, c INT);
INSERT INTO t(i,a,b,c) VALUES(1, 2,3,4);
INSERT INTO t(i,a,b,c) VALUES(2, 20,30,40);
CREATE TABLE log(t VARCHAR(MAX));
CREATE TRIGGER trg_t ON t AFTER UPDATE
AS
BEGIN
IF UPDATE(a)
BEGIN
INSERT INTO log VALUES ('Changed a');
END;
IF UPDATE(b)
BEGIN
INSERT INTO log VALUES ('Changed b');
END;
END;
您需要记住,在SQL Server中,触发器是在语句级别激发的。我更喜欢不涉及触发器的解决方案 从我的头顶上
SELECT PrimaryKeyColumn,SOPNUMBER, SOPTYPE, CMPNTSEQ, LNITMSEQ, ITEMNMBR, QUANTITY, UNITPRCE, PRSTADCD
INTO #mytemptable
FROM SomeTable
WHERE <matches the condition you want>
UPDATE SomeTable
SET SOPNUMBER=@newvalue, etc etc
WHERE <matches the condition you want>
INSERT INTO Audits (audit table columns)
SELECT T.SOPNUMBER,S.SOPNUMBER, etc, etc
FROM #mytemptable T
INNER JOIN SomeTable S
ON S.PrimaryKeyColumn=T.PrimaryKeyColumn
另外,尽量避免使用游标。通常可以使用基于集合的操作。您需要提供一个mvce来演示您的问题。请注意。如果列是UPDATE语句的一部分,UPDATE函数将返回true。它不会评估新旧值是否不同。您的触发器已完全损坏。您有子查询从已删除数据中提取数据。你有一个常见的错误,那就是假设删除中只有一行。这在这一点上是一团糟。如果您想捕获数据更改,它应该是关系型的,而不是单个列中的文本解释。同样,更新不会检查不同的值,所以可以将单价从12.34更改为12.34。我更喜欢不涉及触发器的解决方案。获取与更新的where子句匹配的数据。很好的示例。从我对主要问题的评论中进一步阐述我的观点。如果执行Update t set a=a,b=b,则即使没有更改任何值,日志中也会有两个条目。我知道@lad2025知道这一点,所以会发表评论,让其他人理解这一点。@SeanLange我已经用我的触发器脚本进行了更新,因为我忘了提到它。更新发生在光标内