调用者如何知道存在错误?

时间:2015-02-28 15:21:53

标签: sql-server tsql

请参阅下面的存储过程:

ALTER PROCEDURE GetPerson2

AS
BEGIN TRY
    BEGIN TRANSACTION;
    DECLARE @Count AS INT;
    SET @Count = 1 / 0;
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    ROLLBACK;
    PRINT 'there was an error';
END CATCH

我可以这样称呼它:

EXECUTE getperson2 ;

IF @@ERROR > 0
    PRINT 'there was an error outer';

当我打电话给我时,我想:'外面有一个错误'会被打印到屏幕上。但事实并非如此。调用者如何知道存在错误。我是否必须创建一个输出变量来保存错误代码,然后测试它是否大于0?

我试图在嵌套事务的场景中理解这一点。

1 个答案:

答案 0 :(得分:1)

你"消费"通过CATCH处理错误。使用CATCH中的RaIsError向来电者报告错误。

CREATE PROCEDURE GetPerson2

AS
SET NOCOUNT, XACT_ABORT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- Scope is this stored procedure.
DECLARE @LocalTransaction AS BIT = CASE 
WHEN @@TranCount = 0 THEN 1 ELSE 0 
END;
BEGIN TRY
    IF @LocalTransaction = 1
        BEGIN TRANSACTION;
    -- Do your work here.
    --   You can use   RaIsError   to throw an exception, e.g.
    --   if validating an input fails.
    DECLARE @MyTable AS TABLE (
        Thing INT NOT NULL);
    INSERT  INTO @MyTable (Thing)
    VALUES               (42),
    (NULL);
    IF @LocalTransaction = 1
        COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    -- Save the exception.
    DECLARE @ErrorLine AS INT = Error_Line();
    DECLARE @ErrorMessage AS NVARCHAR (4000) = Error_Message();
    DECLARE @ErrorNumber AS INT = Error_Number();
    DECLARE @ErrorProcedure AS NVARCHAR (126) = Error_Procedure();
    DECLARE @ErrorSeverity AS INT = Error_Severity();
    DECLARE @ErrorState AS INT = Error_State();
    DECLARE @NewLine AS CHAR (2) = Char(13) + Char(10); -- '\r\n'.
    -- Rollback only transactions when there is an active transaction that we started.
    IF Xact_State() <> 0
       AND @LocalTransaction = 1
        ROLLBACK;
    RAISERROR ('%s%s#%i [Proc: %s/Line %i]', @ErrorSeverity, @ErrorState, @ErrorMessage, @NewLine, @ErrorNumber, @ErrorProcedure, @ErrorLine); -- Exit with the exception.set @ErrorSeverity = 16;--case when @ErrorSeverity > 5 then @ErrorSeverity else 6 end;
    RETURN @ErrorNumber;
END CATCH;
RETURN 0;


GO
DECLARE @Error AS INT = 0;

EXECUTE @Error = GetPerson2 ;

PRINT 'Error: ' + CAST (@Error AS VARCHAR (10));

SELECT *
FROM   sys.messages
WHERE  message_id = @Error
       AND language_id = 1033;