微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQL Server:插入事务中的表中以记录错误发生?

如何解决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 举报,一经查实,本站将立刻删除。