如何解决SQL Server:插入事务中的表中以记录错误发生?
| 我有一个SP(存储过程),其中包含一些T-sql语句..... 所有的T-sql语句都在一个事务块中,并且通过发生任何错误,我回滚了每一件事。 像这样:BEGIN TRANSACTION
.....
.....
IF @X=1
BEGIN
declare cu cursor for select col1,col2 from Table1 where Id=@Y
open cu
fetch next from cuinto @A,@B
while @@Fetch_Status = 0
BEGIN
.....
......
IF @@ERROR <>0
BEGIN
ROLLBACK TRANSACTION
RETURN
END
END
.....
.....
Sp不能正常运行,我找不到它的树脂.....
我认为通过在表中插入一些数据来记录sp中的每个操作是一个好主意
我的问题是:
因为它使用事务,所以每次插入都会回滚.....
你怎么看?还有其他办法吗?
谢谢
解决方法
3件事:
1)请,如果不需要,请不要使用游标。
2)您可以使用RAISERROR WITH LOG或将数据插入表变量中,然后在回滚事务后将其插入到真实表中进行记录。这是可能的,因为表变量与事务无关。
3)使用try catch块
, 现在没有理由使用@@ ERROR:TRY / CATCH更加可靠。要了解更多信息,我建议阅读Erland Sommarskog的“ SQL 2005及更高版本中的错误处理”,这是有关该主题的权威文章之一。
在这种情况下,如果没有TRY / CATCH,则某些错误将被批中止:这意味着代码停止并且没有错误被捕获。除编译错误外,这已通过TRY / CATCH修复。
该模板取自我之前的答案包含TRY CATCH ROLLBACK模式的嵌套存储过程?
CREATE PROCEDURE [Name]
AS
SET XACT_ABORT,NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SELECT @starttrancount = @@TRANCOUNT
IF @starttrancount = 0
BEGIN TRANSACTION
[...Perform work,call nested procedures...]
IF @starttrancount = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION
RAISERROR [rethrow caught error using @ErrorNumber,@ErrorMessage,etc]
-- if desired INSERT ExceptionLogTable () ..
END CATCH
GO
如果使用SET XACT_ABORT ON(我认为这是最佳做法),则在任何CATCH块中,@@ trancount均为零。因此,除了引发错误之外,您还可以根据需要在此处写入日志记录表。
, 我重写了您的代码,以使用Transaction
和Try Catch
给您一个真实的例子
CREATE PROCEDURE [dbo].[mySP]
(
@X int,@Y int,@Return_Message VARCHAR(1024) = \'\' OUT
)
AS
SET NOCOUNT ON;
Declare @A varchar(100) @B varchar(100)
BEGIN TRY
BEGIN TRAN
IF @X=1
BEGIN
declare cu cursor for select col1,col2 from Table1 where Id=@Y
open cu
fetch next from cu into @A,@B
while @@Fetch_Status = 0
BEGIN
-- .....
-- do your stuff
FETCH NEXT FROM cu into @A,@B
END
END
COMMIT TRAN
SELECT @Return_Message = \'All OK\'
/*************************************
* Return from the Stored Procedure
*************************************/
RETURN 1 -- success
END TRY
BEGIN CATCH
/*************************************
* if errors rollback
*************************************/
IF @@TRANCOUNT > 0 ROLLBACK
SELECT @Return_Message = @ErrorStep + \' \'
+ cast(ERROR_NUMBER() as varchar(20)) + \' line: \'
+ cast(ERROR_LINE() as varchar(20)) + \' \'
+ ERROR_MESSAGE() + \' > \'
+ ERROR_PROCEDURE()
/*************************************
* Return from the Stored Procedure
*************************************/
RETURN 0 -- fail
END CATCH
SP用法:
declare @ret int,@Return_Message VARCHAR(1024)
EXEC @ret = mySP 1,2,@Return_Message OUTPUT
-- the SP Fail so print or store the return message with errors ...
if @ret = 0 print @Return_Message
, 您还可以使用Try Catch实现异常处理
Begin Try
BEGIN TRANSACTION
.....
.....
IF @X=1
BEGIN
declare cu cursor for select col1,col2 from Table1 where Id=@Y
open cu
fetch next from cuinto @A,@B
while @@Fetch_Status = 0
BEGIN
.....
......
//Your insert statement....
END
.....
.....
Commit Tran
End Try
Begin Catch
Rollback Tran
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT @ErrorMessage = ERROR_MESSAGE(),@ErrorSeverity = ERROR_SEVERITY(),@ErrorState = ERROR_STATE();
-- Use RAISERROR inside the CATCH block to return
-- error information about the original error that
-- caused execution to jump to the CATCH block.
RAISERROR (@ErrorMessage,-- Message text.
@ErrorSeverity,-- Severity.
@ErrorState -- State.
);
End Catch
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。