我试图测试触发器中哪些列已更新。我知道可以使用UPDATE()
函数,如
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;
每次只测试Column1时,即使更新行时所有三列都已更新,其他列也会被忽略。
编辑:忘记提及更新是在光标内发生的,所以不确定是否是导致我出现问题的原因?
答案 0 :(得分:2)
当然可以。来自Xapian:
返回一个布尔值,指示是对表或视图的指定列进行INSERT还是UPDATE尝试。 UPDATE()用于Transact-SQL INSERT或UPDATE触发器主体内的任何位置,以测试触发器是否应执行某些操作。
示例:
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;
<强> UPDATE() 强>
您需要记住,在语句级别触发SQL Server触发器。
答案 1 :(得分:0)
我更喜欢不涉及触发器的解决方案。
脱离我的头顶......
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
还尽量避免使用游标。通常可以使用基于集合的operaitons。