我有以下触发器
第一次触发:
ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update]
ON [dbo].[DIENSTLEISTUNG]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @intNewID int
INSERT INTO [DIENSTLEISTUNG]
(DESCRIPTION, QUANTITY,
PRICE, AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR,
AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID,
UPDATE_USER, UPDATE_DATE,
PERMISSIONS, KONTRAKTPOSITION,ITEMNUMBER,
PRIORITY, VALID)
SELECT i.DESCRIPTION, i.QUANTITY, i.PRICE, i.AZ_MO,
i.AZ_DI,i.AZ_MI,i.AZ_DO,i.AZ_FR,
i.AZ_SA,i.AZ_SO,i.SERVICETYPE_ID, i.UPDATE_USER,GETDATE(),
i.PERMISSIONS, i.KONTRAKTPOSITION,i.ITEMNUMBER, i.PRIORITY, 'Y'
FROM INSERTED i
JOIN deleted d ON i.ID=d.ID
WHERE i.PRICE<>d.PRICE
or i.DESCRIPTION<>d.DESCRIPTION
IF ( UPDATE (PRICE) OR UPDATE (DESCRIPTION) )
UPDATE S
SET s.VALID = 'N'
FROM SERVICE s
JOIN INSERTED i ON I.ID = S.ID
IF UPDATE(PRIORITY)
UPDATE s
SET s.PRIORITY= i.PRIORITY
FROM SERVICE s
JOIN INSERTED i ON i.ID = s.ID
SET NOCOUNT OFF;
END
如果原始行发生更改,第一个Trigger会使用新ID复制整行,触发器也会设置一个标志。旧行获取标志VALID = 'N'
,新行获取标志VALID = 'Y'
。如果PRICE
或DESCRIPTION
更新,则触发器仅会创建新行。到现在为止还挺好。
我的问题是,如果我想更新新行中的PRIORITY
,则触发器再次触发并将标志设置为VALID = 'N'
。这不应该发生。我只想更新优先级而不创建新行或更新另一列。
感谢您的帮助
答案 0 :(得分:2)
您无法阻止触发器触发 - 如果它存在且未禁用,将触发。这就是触发器的工作方式。
您可以做的是检查触发器内哪些列已更新。所以你可以在一个单一的触发器中做这样的事情:
CREATE TRIGGER [dbo].[DIENSTLEISTUNG_Update]
ON [dbo].[DIENSTLEISTUNG]
FOR UPDATE
AS
IF UPDATE(PRICE)
... (do what you need to do if PRICE is updated)...
IF UPDATE(DESCRIPTION)
... (do what you need to do if DESCRIPTION is updated)...
IF UPDATE(PRIORITY)
... (do what you need to do if PRIORITY is updated)...
使用UPDATE()
函数检查给定列是否已更新 - 如果已更新,请对其执行操作。请参阅MSDN docs on how to use the UPDATE()
function。
答案 1 :(得分:1)
您可以仅在某些列或一列上触发触发器。 像这样。
CREATE TRIGGER tr_something ON myTable
FOR INSERT, UPDATE
AS
IF UPDATE(myColumn)
BEGIN
-- do what you want
END
下面的帖子提供了更多细节,似乎我要慢一点:)
答案 2 :(得分:0)
您可以做的是设置您所在会话的上下文信息:
SET Context_Info 0x55555
然后在您的触发器中检查上下文信息以决定要做什么:
DECLARE @Cinfo VARBINARY(128)
SELECT @Cinfo = Context_Info()
IF @Cinfo = 0x55555
RETURN