嵌套Try Catch如何进入Outer catch块?

时间:2017-06-06 02:18:42

标签: tsql

如何到达At" Outer catch block,删除所有插入的记录?"当我在两个内部Try Catch块中创建错误时,它仍然没有进入Outer catch块。我每批都有大约1000条记录发布,每条记录插入约20个表。所以我需要尝试所有插入查询而不是在第一个错误处停止,这样我就可以获得详细的日志并快速响应所有数据错误。

CREATE TABLE [dbo].[StudentDetails](
    [Roll] [int] NULL,
    [Name] [varchar](50) NULL,
    [Address] [varchar](50) NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[Library](
    [Roll] [int] NULL,
    [Name] [varchar](50) NULL,
    [Address] [varchar](50) NULL
) ON [PRIMARY]

- 1错误

BEGIN TRY
  print 'At Outer Try Block'
   BEGIN TRY
      print 'At Inner Try Block 1'
      INSERT INTO StudentDetails(Roll, [Name])
        VALUES('a', 'Abhijit')  -- Throwing Exception
   END TRY
   BEGIN CATCH
      print 'At Inner catch Block 1, Log Errors'
   END CATCH
   BEGIN TRY
      print 'At Inner Try Block 2'
      INSERT INTO StudentDetails(Roll, [Name])
        VALUES('1', 'Abhijit')  -- Throwing Exception
   END TRY
   BEGIN CATCH
      print 'At Inner catch Block 2, Log Errors'
   END CATCH
      --... to 20 inserts
END TRY
BEGIN CATCH
   print 'At Outer catch block, if an error delete any inserted records'
END CATCH

Query result
At Outer Try Block
At Inner Try Block 1
At Inner catch Block 1, Log Errors
At Inner Try Block 2

- 2个错误

BEGIN TRY
  print 'At Outer Try Block'
   BEGIN TRY
      print 'At Inner Try Block 1'
      INSERT INTO StudentDetails(Roll, [Name])
        VALUES('a', 'Abhijit')  -- Throwing Exception
   END TRY
   BEGIN CATCH
      print 'At Inner catch Block 1, Log Errors'
   END CATCH
   BEGIN TRY
      print 'At Inner Try Block 2'
      INSERT INTO StudentDetails(Roll, [Name])
        VALUES('a', 'Abhijit')  -- Throwing Exception
   END TRY
   BEGIN CATCH
      print 'At Inner catch Block 2, Log Errors'
   END CATCH
      --... to 20 inserts
END TRY
BEGIN CATCH
   print 'At Outer catch block, if an error delete any inserted records'
END CATCH

Query result
At Outer Try Block
At Inner Try Block 1
At Inner catch Block 1, Log Errors
At Inner Try Block 2
At Inner catch Block 2, Log Errors

2 个答案:

答案 0 :(得分:1)

尝试使用TRANTRANSACTION,然后您将不需要嵌套的尝试捕获。 ROLLBACK TRAN将撤消任何INSERT / UPDATE / DELETE ...

请记住,您执行的任何日志记录都需要在ROLLBACK TRAN之后完成,或者日志也将被撤消:)

BEGIN TRY
    PRINT 'At Try Block 1'
    BEGIN TRAN;
        INSERT INTO StudentDetails(Roll, [Name])
        VALUES('a', 'Abhijit')  -- Throwing Exception
    COMMIT TRAN;
END TRY
BEGIN CATCH
    PRINT 'At catch Block 1, Log Errors'
    ROLLBACK TRAN;
END CATCH
BEGIN TRY
    PRINT 'At Try Block 2'
    BEGIN TRAN;
        INSERT INTO StudentDetails(Roll, [Name])
        VALUES('a', 'Abhijit')  -- Throwing Exception
    COMMIT TRAN;
END TRY
BEGIN CATCH
    PRINT 'At catch Block 2, Log Errors'
    ROLLBACK TRAN;
END CATCH
--... to 20 inserts

答案 1 :(得分:1)

我同意@Alex你应该在你的情况下为了失败而回滚交易。

以下是嵌套TRY - CATCH块的示例:

-- Throw from inner catch to outer catch block
BEGIN TRY
    PRINT 'Outer Try';
    --Throw 50000, 'Outer Error', 1; -- Uncomment this to skip the inner try.

    BEGIN TRY
        PRINT 'Inner Try';
        Throw 50000, 'Inner Error', 1;
    END TRY
    BEGIN CATCH
        PRINT 'Inner Catch';
        Throw 50000, 'Inner Catch Error', 1;
    END CATCH

END TRY
BEGIN CATCH
    PRINT 'Outer Catch';
    PRINT ERROR_MESSAGE();
END CATCH

-- OUTPUT:
-- Outer Try
-- Inner Try
-- Inner Catch
-- Outer Catch
-- Inner Catch Error