我在对表的插入语句上有一个触发器(可能会修改插入值)。 如果触发器中发生错误,我要记录它。并且仍必须插入INSERT。 因此,我使用了一个TRY / CATCH块,其中catch部分将进行日志记录。 问题是我只能回滚整个事务,然后再记录。但是然后插入内容也会回滚。
在Sql Server 2008上运行...
到目前为止很好。
要测试catch部分中的日志记录,我正在使用RAISERROR。 (也许这是一个问题?我将回到该部分)。然后,我将插入内容运行到表中。
在触发器中,我放置了一个BEGIN TRANSACTION triggerTransaction2。我命名了它,因此可以回滚该特定事务。注意,insert语句已经开始了事务。 但是问题是我无法回滚嵌套的(triggerTransaction2)事务。仅整个交易(使用不带名称的ROLLBACK)。
如果我看着XACT_STATE(),那么它是-1。这应该表示“它只能请求完全回滚交易”。
我试图简化代码,并希望它仍然有意义。 我也遵循了这个example-对我有用,但也不是嵌套事务。
所以我在想,将RAISERROR与所选值一起使用不是很好。
触发器的伪代码:
CREATE TRIGGER [dbo].[Trigger_SomeTableStatus]
ON [dbo].[SomeTable]
FOR INSERT
AS
BEGIN
SET NoCount ON
-- declaring som variables; DECLARE @isActive BIT;
BEGIN TRY
BEGIN TRANSACTION triggerTransaction2
-- SAVE TRANSACTION triggerTransaction2
-- some logic ...
RAISERROR(' Test error message; *failed* ', 16, 1);
COMMIT TRANSACTION triggerTransaction2
END TRY
BEGIN CATCH
-- HERE XACT_STATE() = -1)
ROLLBACK TRANSACTION triggerTransaction2 -- Cannot rollback with the name
BEGIN TRY
BEGIN TRANSACTION triggerTransactionLog
-- Do the logging..
COMMIT TRANSACTION triggerTransactionLog
END TRY
BEGIN CATCH
-- -- Logging of error failed...
END CATCH
END CATCH
END
答案 0 :(得分:0)
是的,这是因为当您进行“回滚”时,整个交易都将被取消。 您必须在内存中创建一个表,例如:
DECLARE @Log AS TABLE
(
Description NVARCHAR(100)
);
然后,在@Log表中插入要登录的内容。 最后,将@Log表中的内容插入到END TRY和END CATCH之前(或SP结束之前)的DB日志表中。