在T#中是否存在与C#相同的"抛出"; 重新抛出异常?

Nei*_*ell 26 t-sql exception-handling

标题真的是这个问题:在T#中是否存在与C#相同的"抛出"; 重新抛出异常?

在C#中,可以这样做:

try
{
    DoSomethingThatMightThrowAnException();
}
catch (Exception ex)
{
    // Do something with the exception
    throw; // Re-throw it as-is.
}
Run Code Online (Sandbox Code Playgroud)

T-SQL的BEGIN CATCH功能是否有相同的功能?

Don*_*yrd 33

您可以使用RAISERROR.从RAISERROR上的MSDN文档:

BEGIN TRY
    -- RAISERROR with severity 11-19 will cause execution to 
    -- jump to the CATCH block
    RAISERROR ('Error raised in TRY block.', -- Message text.
               16, -- Severity.
               1 -- State.
               );
END TRY
BEGIN CATCH
    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;
Run Code Online (Sandbox Code Playgroud)

编辑:

这与c#throw或者它不是一回事throw ex.正如@henrikstaunpoulsen指出你没有在新错误中得到原始错误号(RAISERROR受限于它可以使用的数字).您必须使用某种约定并从消息中解析信息(如果可用).

MSDN 在Transact-SQL中有一篇文章使用TRY ... CATCH,我使用了一些代码来创建下面的测试:

use test;
GO

IF OBJECT_ID (N'usp_RethrowError',N'P') IS NOT NULL
    DROP PROCEDURE usp_RethrowError;
GO

CREATE PROCEDURE usp_RethrowError AS
    IF ERROR_NUMBER() IS NULL
        RETURN;

    DECLARE 
        @ErrorMessage    NVARCHAR(4000),
        @ErrorNumber     INT,
        @ErrorSeverity   INT,
        @ErrorState      INT,
        @ErrorLine       INT,
        @ErrorProcedure  NVARCHAR(200);

    SELECT 
        @ErrorNumber = ERROR_NUMBER(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE(),
        @ErrorLine = ERROR_LINE(),
        @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-');

    SELECT @ErrorMessage = 
        N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 
            'Message: '+ ERROR_MESSAGE();

    RAISERROR 
        (
        @ErrorMessage, 
        @ErrorSeverity, 
        @ErrorState,               
        @ErrorNumber,    -- parameter: original error number.
        @ErrorSeverity,  -- parameter: original error severity.
        @ErrorState,     -- parameter: original error state.
        @ErrorProcedure, -- parameter: original error procedure name.
        @ErrorLine       -- parameter: original error line number.
        );
GO

PRINT 'No Catch'
DROP TABLE XXXX

PRINT 'Single Catch'
BEGIN TRY
    DROP TABLE XXXX
END TRY
BEGIN CATCH
    EXEC usp_RethrowError;
END CATCH;

PRINT 'Double Catch'
BEGIN TRY
    BEGIN TRY
        DROP TABLE XXXX
    END TRY
    BEGIN CATCH
        EXEC usp_RethrowError;
    END CATCH;
END TRY
BEGIN CATCH
    EXEC usp_RethrowError;
END CATCH;
Run Code Online (Sandbox Code Playgroud)

其中产生以下输出:

No Catch
Msg 3701, Level 11, State 5, Line 3
Cannot drop the table 'XXXX', because it does not exist or you do not have permission.
Single Catch
Msg 50000, Level 11, State 5, Procedure usp_RethrowError, Line 25
Error 3701, Level 11, State 5, Procedure -, Line 7, Message: Cannot drop the table 'XXXX', because it does not exist or you do not have permission.
Double Catch
Msg 50000, Level 11, State 5, Procedure usp_RethrowError, Line 25
Error 50000, Level 11, State 5, Procedure usp_RethrowError, Line 25, Message: Error 3701, Level 11, State 5, Procedure -, Line 16, Message: Cannot drop the table 'XXXX', because it does not exist or you do not have permission.
Run Code Online (Sandbox Code Playgroud)


ser*_*iom 14

在SQL 2012中,他们添加了新的THROW关键字,该关键字也可用于重新抛出异常

USE tempdb;
GO
CREATE TABLE dbo.TestRethrow
(    ID INT PRIMARY KEY
);
BEGIN TRY
    INSERT dbo.TestRethrow(ID) VALUES(1);
--  Force error 2627, Violation of PRIMARY KEY constraint to be raised.
    INSERT dbo.TestRethrow(ID) VALUES(1);
END TRY
BEGIN CATCH

    PRINT 'In catch block.';
    THROW;
END CATCH;
Run Code Online (Sandbox Code Playgroud)

http://msdn.microsoft.com/en-us/library/ee677615.aspx