请参阅下面的存储过程:
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?
我试图在嵌套事务的场景中理解这一点。
答案 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;