如果我的触发器在存储过程中更新后失败怎么办?
What if my trigger fails after an update inside a stored procedure?
如果我在 SQL 服务器的存储过程中有一个更新,并且存储过程成功运行,但是,无论出于何种原因,该更新的触发失败,我的更新会被回滚吗?
是的,如果在您的触发器中发生回滚或任何 运行时间错误,它将回滚上面的特定(或隐含)事务。
要在您询问的更新中看到这种情况,运行 这个:
DROP TABLE IF EXISTS dbo.MyTable;
DROP TABLE IF EXISTS dbo.OtherTable;
GO
CREATE TABLE dbo.MyTable (ID INT);
GO
CREATE TABLE dbo.OtherTable (ID INT);
GO
CREATE TRIGGER dbo.UpdateTrigger
ON dbo.MyTable
FOR UPDATE
AS
BEGIN
INSERT dbo.OtherTable (ID) VALUES ('Blah');
END;
GO
INSERT dbo.MyTable (ID) VALUES (1);
GO
UPDATE dbo.MyTable SET ID = 2;
GO
SELECT ID FROM dbo.MyTable;
SELECT ID FROM dbo.OtherTable;
您会看到 MyTable 中 ID 的值仍然是 1,而 OtherTable 仍然是空的,因为触发器在 UPDATE 期间抛出了错误。
即使您在触发器和更新批次中设置 XACT_ABORT OFF
,更新仍会回滚。
DROP TABLE IF EXISTS dbo.MyTable;
DROP TABLE IF EXISTS dbo.OtherTable;
GO
CREATE TABLE dbo.MyTable (ID INT);
GO
CREATE TABLE dbo.OtherTable (ID INT);
GO
CREATE TRIGGER dbo.UpdateTrigger
ON dbo.MyTable
FOR UPDATE
AS
BEGIN
SET XACT_ABORT OFF;
INSERT dbo.OtherTable (ID) VALUES ('Blah');
END;
GO
INSERT dbo.MyTable (ID) VALUES (1);
GO
SET XACT_ABORT OFF;
UPDATE dbo.MyTable SET ID = 2;
GO
SELECT ID FROM dbo.MyTable;
SELECT ID FROM dbo.OtherTable;
如果即使触发器失败也想继续更新,那么您应该在触发器中使用 TRY/CATCH 来处理 运行 时间错误并允许触发器完成。
如果我在 SQL 服务器的存储过程中有一个更新,并且存储过程成功运行,但是,无论出于何种原因,该更新的触发失败,我的更新会被回滚吗?
是的,如果在您的触发器中发生回滚或任何 运行时间错误,它将回滚上面的特定(或隐含)事务。
要在您询问的更新中看到这种情况,运行 这个:
DROP TABLE IF EXISTS dbo.MyTable;
DROP TABLE IF EXISTS dbo.OtherTable;
GO
CREATE TABLE dbo.MyTable (ID INT);
GO
CREATE TABLE dbo.OtherTable (ID INT);
GO
CREATE TRIGGER dbo.UpdateTrigger
ON dbo.MyTable
FOR UPDATE
AS
BEGIN
INSERT dbo.OtherTable (ID) VALUES ('Blah');
END;
GO
INSERT dbo.MyTable (ID) VALUES (1);
GO
UPDATE dbo.MyTable SET ID = 2;
GO
SELECT ID FROM dbo.MyTable;
SELECT ID FROM dbo.OtherTable;
您会看到 MyTable 中 ID 的值仍然是 1,而 OtherTable 仍然是空的,因为触发器在 UPDATE 期间抛出了错误。
即使您在触发器和更新批次中设置 XACT_ABORT OFF
,更新仍会回滚。
DROP TABLE IF EXISTS dbo.MyTable;
DROP TABLE IF EXISTS dbo.OtherTable;
GO
CREATE TABLE dbo.MyTable (ID INT);
GO
CREATE TABLE dbo.OtherTable (ID INT);
GO
CREATE TRIGGER dbo.UpdateTrigger
ON dbo.MyTable
FOR UPDATE
AS
BEGIN
SET XACT_ABORT OFF;
INSERT dbo.OtherTable (ID) VALUES ('Blah');
END;
GO
INSERT dbo.MyTable (ID) VALUES (1);
GO
SET XACT_ABORT OFF;
UPDATE dbo.MyTable SET ID = 2;
GO
SELECT ID FROM dbo.MyTable;
SELECT ID FROM dbo.OtherTable;
如果即使触发器失败也想继续更新,那么您应该在触发器中使用 TRY/CATCH 来处理 运行 时间错误并允许触发器完成。