用 THROW 替换 RAISERROR

问题描述 投票:0回答:2

在我的历史过程中,我总是捕获异常,然后在

ROLLBACK
之后引发它。 我在 MSDN 中看到推荐的方法(对于 SQL2012+)是
THROW

基于此示例过程:

CREATE PROC my_procName

    @id int

AS
    BEGIN TRY
        BEGIN TRAN

            UPDATE [tbl_A] WHERE (ID=@id);
            UPDATE [tbl_B] WHERE (fkID=@id);
            UPDATE [tbl_C] WHERE (fkID=@id);

        COMMIT TRAN
    END TRY

    BEGIN CATCH
        ROLLBACK TRAN
        DECLARE @ErrMsg nvarchar(4000)
        DECLARE @ErrSeverity int
        SET @ErrMsg = ERROR_MESSAGE()
        SET @ErrSeverity = ERROR_SEVERITY()
        RAISERROR(@ErrMsg, @ErrSeverity, 1)
    END CATCH
GO

这是抛出异常同时保留

ROLLBACK
的正确方法吗?

CREATE PROC my_procName

    @id int

AS
    BEGIN TRY
        BEGIN TRAN

            UPDATE [tbl_A] WHERE (ID=@id);
            UPDATE [tbl_B] WHERE (fkID=@id);
            UPDATE [tbl_C] WHERE (fkID=@id);

        COMMIT TRAN
    END TRY

    BEGIN CATCH
        ROLLBACK TRAN
        THROW
    END CATCH
GO

我已经查看了 MSDN、Google 和此网站的示例,但没有一个包含

ROLLBACK
,所以这只是一个需要绝对确定的快速问题。

sql-server t-sql sql-server-2012
2个回答
2
投票

仅供记录,THROW 语句之前的语句应以分号终止。但通常您的方法是正确的 - THROW 结束批处理,因此必须是您要在 catch 块中执行的最后一条语句。您可以选择将 THROW 与参数一起使用:

THROW [ { error_number | @local_variable },
        { message | @local_variable },
        { state | @local_variable } ] 
[ ; ]


0
投票

不,你实际上根本不需要any

CATCH

您需要做的就是顶部的

SET XACT_ABORT ON;
,服务器将处理回滚。如果您需要的只是回滚和重新抛出,那么捕获是没有意义的。

CREATE PROC my_procName
    @id int
AS

SET XACT_ABORT, NOCOUNT ON;

BEGIN TRAN;

UPDATE [tbl_A]
WHERE ID = @id;

UPDATE [tbl_B]
WHERE fkID = @id;

UPDATE [tbl_C]
WHERE fkID = @id;

COMMIT;
© www.soinside.com 2019 - 2024. All rights reserved.