Если ваши хранимые процедуры следуют такого рода инфраструктуре, то ваша ошибка должна быть передана обратно в блок CATCH
в верхней вызывающей стороне:
CREATE PROCEDURE y
AS
BEGIN
SELECT 1 / 0;
END;
GO
CREATE PROCEDURE x
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
EXEC y;
SELECT 0 AS result;
END TRY
BEGIN CATCH
PRINT error_message();
SELECT 1 AS result;
END CATCH;
END;
GO
EXEC x;
Если я выполню это, тогда процедура y сгенерируетошибка «Ошибка деления на ноль», которая затем передается обратно в процедуру x, где она обрабатывается и сообщается.
Если в процедуре y есть блок TRY-CATCH
, то это будет использовать ошибку и ничегобудет отправлен обратно в процедуру x.
Кроме того, вы можете использовать RETURN 0
или RETURN 1
, чтобы возвратить статус успеха / неудачи вашей хранимой процедуры, вместо использования запроса SELECT
, чтобы сделать это,это просто лучшая практика.Если у вас есть дополнительная информация для передачи, например, сообщение об ошибке, вы можете использовать для этого параметр OUTPUT
.
Например:
CREATE PROCEDURE y
AS
BEGIN
SELECT 1 / 0;
END;
GO
CREATE PROCEDURE x (
@message VARCHAR(512) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
EXEC y;
RETURN 0;
END TRY
BEGIN CATCH
SELECT @message = error_message();
RETURN 1;
END CATCH;
END;
GO
DECLARE @message VARCHAR(512);
DECLARE @ret INT;
EXEC @ret = x @message OUTPUT;
SELECT @ret, @message;
Или вотПример повторного прохождения внутреннего исключения снова:
CREATE PROCEDURE y (
@message VARCHAR(512) OUTPUT)
AS
BEGIN
BEGIN TRY
SELECT 1 / 0;
RETURN 0;
END TRY
BEGIN CATCH
SELECT @message = 'Inner ' + ERROR_MESSAGE();
RETURN 1;
END CATCH;
END;
GO
CREATE PROCEDURE x (
@message VARCHAR(512) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
DECLARE @ret INT;
EXEC @ret = y @message OUTPUT;
RETURN @ret;
END TRY
BEGIN CATCH
SELECT @message = 'Outer ' + ERROR_MESSAGE();
RETURN 1;
END CATCH;
END;
GO
DECLARE @message VARCHAR(512);
DECLARE @ret INT;
EXEC @ret = x @message OUTPUT;
SELECT @ret, @message;
При запуске вы получите статус возврата 1 (исключение) и сообщение об ошибке: «Обнаружена ошибка внутреннего деления на ноль». ".Итак, мы знаем, что эта ошибка на самом деле была вызвана процедурой y, хотя процедура x сообщила об этом.