如果更新表A,则会触发触发器。该触发器调用另一个SP进行一些处理。 如果SP失败,是否有可能恢复表A上发生的更新?
我在更新之后有一个代码“如果是Sqlca.SqlCode”,并且这个代码总是有0来进行更新。
请帮助!!
答案 0 :(得分:2)
是的,如果触发器遇到错误(内部或通过调用某些外部过程)并回滚事务,它将回滚整个事务,包括导致触发器触发的任何UPDATE
。如果不是您想要的行为,有多种方法可以解决这个问题:
使用TRY / CATCH
吸收外部过程中的任何错误,或将过程逻辑移动到触发器中,或者将正确的错误处理添加到存储过程中,这样,如果您不关心错误发生在那里,它没有起泡并回滚所有东西。
使用INSTEAD OF
触发器 - 结合TRY / CATCH
(或者可能首先提交自己的UPDATE
),您应该能够更新表而无需关心外部是否存储程序失败。
INSTEAD OF
触发器的示例:
USE tempdb;
GO
CREATE TABLE dbo.flooblat(id INT PRIMARY KEY, name VARCHAR(32));
INSERT dbo.flooblat(id,name) VALUES(1, 'Bob');
GO
CREATE PROCEDURE dbo.oh_my
AS
SELECT 1/0;
GO
CREATE TRIGGER dbo.trFlooblat
ON dbo.flooblat
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE f SET f.name = i.name
FROM dbo.flooblat AS f
INNER JOIN inserted AS i
ON f.id = i.id;
COMMIT TRANSACTION;
EXEC dbo.oh_my;
END
GO
UPDATE dbo.flooblat SET name = 'Frank';
GO
SELECT id, name FROM dbo.flooblat;
GO
结果:
Msg 8134,Level 16,State 1,Procedure oh_my
遇到零误差。 该声明已经终止。
然而,SELECT
显示,即使触发器中发生错误, UPDATE
提交后也发生了错误 - 因此不同于AFTER
触发器(没有正确的错误处理),我们能够防止错误回滚我们已完成的所有工作。
id name
---- -----
1 Frank
答案 1 :(得分:1)
触发器可以在执行DML之后执行操作,执行DML的INSTEAD OF等等。所以是的,如果SP失败,有可能发生更新(dml) - 只是取决于你如何写它/你使用什么功能。
在这里阅读一下触发器:http://technet.microsoft.com/en-us/library/ms189799%28v=sql.105%29.aspx
如果您想在问题中找到触发器的更具体的答案,那么您需要发布代码。