[英]SQL Server update trigger is not working
有一个具有更新触发器的数据库表。 每当更新列时,都会自动计算其列之一。
我已经调整了触发器,我想再次在所有行上运行它。 在SQL Server Management Studio中,如果我在表上选择“编辑前200行”并编辑其中一行,则更新触发器有效。 但是当我写一个查询像:
UPDATE MyTable
SET SomeIrrelevantColumn = 0
触发器不起作用,应该由触发器计算的列保持不变。
如何在所有行上手动运行触发器?
编辑:这是触发器:
USE [MY_DATABASE]
GO
/****** Object: Trigger [dbo].[MY_TABLE_AUER] Script Date: 04/24/2013 00:05:23 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[MY_TABLE_AUER]
ON [dbo].[MY_TABLE]
AFTER UPDATE
AS
DECLARE @UPD_COLUMN_A int,
@INS_COLUMN_A int,
@UPD_COLUMN_B int,
@UPD_COLUMN_C varchar(255),
@UPD_COLUMN_D varchar(255),
@UPD_COLUMN_E int,
@UPD_COLUMN_F datetime
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT @UPD_COLUMN_A = _Column_A,
@UPD_COLUMN_B =_Column_B,
@UPD_COLUMN_C = COLUMN_C,
@UPD_COLUMN_D = [Column_D]
FROM DELETED;
IF @UPD_COLUMN_D not like '%SomeString%'
BEGIN
SELECT @INS_COLUMN_A = _Column_A
FROM INSERTED;
IF @UPD_COLUMN_A != @INS_COLUMN_A
BEGIN
SELECT @UPD_COLUMN_E = MAX([_Column_B]),
@UPD_COLUMN_F = MAX([_Column_G])
FROM MY_TABLE
WHERE COLUMN_C = @UPD_COLUMN_C
AND [Column_D] LIKE '%SomeString%';
UPDATE MY_TABLE
SET COLUMN_E = @UPD_COLUMN_E,
COLUMN_F = @UPD_COLUMN_F
WHERE [_Column_B] = @UPD_COLUMN_B;
UPDATE MY_TABLE
SET COLUMN_H = @UPD_COLUMN_B
WHERE [_Column_B] = @UPD_COLUMN_E;
END
END
END
您的触发器做出一个非常普遍但错误的假设,即每行执行一次。 并非如此,它每个动作执行一次-因此,当您更新整个表时,我敢打赌,如果您仔细看,您会看到一行已更新。 *感谢Aaron Bertrand对本介绍段落的评论。
您将需要研究如何基于JOIN(使用inserted
或deleted
元表)执行更新。 例如:
CREATE TRIGGER TR_Sample_U ON dbo.Sample FOR UPDATE -- AFTER is default so not needed
AS
IF EXISTS ( --check for disallowed modifications
SELECT *
FROM
Inserted I
INNER JOIN Deleted D
ON I.SampleID = D.SampleID
WHERE
I.Something <> D.Something
AND I.UpdateDate = D.UpdateDate
)
ROLLBACK TRAN;
这些资源还可以帮助您:
我发现执行此操作的一种方法如下所示:
UPDATE A
SET A.SOME_COLUMN = D.ANOTHER_COLUMN
FROM MY_TABLE AS A
JOIN inserted AS B ON A.ID = B.ID -- Point 1.
JOIN deleted AS C ON A.ID = C.ID
JOIN (SELECT MAX(ID) AS OTHER_ID, GROUP_ID AS OTHER_GROUP_ID -- Point 2.
FROM MY_TABLE AS E
WHERE E.SOME_STRING_COLUMN LIKE '%SomeString%'
GROUP BY E.GROUP_ID) AS D ON A.GROUP_ID = D.OTHER_GROUP_ID
WHERE C.SOME_BOOL_COLUMN != B.SOME_BOOL_COLUMN -- Point 3.
AND C.SOME_STRING_COLUMN NOT LIKE '%SomeString%'
UPDATE
语句之后,我继续将表加入到“插入”和“删除”特殊表中(有关这些表的更多信息, 请访问http://www.mssqltips.com/sqlservertip/2342/understanding-sql-server-inserted并删除了dml触发表/ )。 这样,我将只浏览已更新的行,而不会与其他行混淆。 您只能加入其中之一,但是我需要在更新操作前后的值之间的一列中看到差异。 这就是为什么我都使用它们。 “删除”具有更新操作之前的状态的行,而“插入”具有更新操作之后的状态的行。 GROUP_ID
,并且我进行了字符串测试,以确保我得到的新行符合父级条件,您可以在那里定义任何类型的过滤器。 基本上,您编写另一个查询以根据更新后的行查找该行,然后对返回的表进行另一个JOIN
。 WHERE
子句来确保仅通过查看SOME_BOOL_COLUMN
列来更新状态已更改的行。 您可以在此处输入任何标准。 如您所见,我检查了更新前后列状态之间的差异。 不过,请花一点心血来写这里写的任何东西,因为它来自几乎没有SQL经验的人。
请尝试在触发器中使用以下代码。
//Check if the column is getting updated
if (Update(column1) or Update(Column2)...etc)
Begin
Write the entire logic inside this loop..!
End
希望这可以.. !!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.