我将在发送准备好的记录集之前使用简单的select语句报告存储过程的结果(无论是成功还是有错误)。所以我只是在发送真实记录集之前插入这个select语句。但是,即使我在事务中包装这两个select语句以使它们成为原子,如果第二个select语句引发错误,则第一个select执行并给出“ok”#39;和'错误'同时。这是代码:
CREATE PROCEDURE my_procedure
@id INT = NULL
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
SELECT 1 AS [status], 'OK' AS [message];
SELECT 1/0;
COMMIT;
END TRY
BEGIN CATCH
ROLLBACK;
SELECT 0 AS [status], ERROR_MESSAGE() AS [message];
END CATCH;
END;
如果第二个语句成功,首先如何选择语句?
答案 0 :(得分:1)
可能会在TRY/CATCH
之外声明一些变量。如果抛出错误,则在CATCH
中更改其值。在TRY/CATCH
之后,显示变量的值。
ALTER PROCEDURE my_procedure
@id INT = NULL
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @status BIT = 1; --set status variable here
DECLARE @message VARCHAR(MAX) = 'OK'; --set message variable here
BEGIN TRY
BEGIN TRANSACTION;
SELECT 1/0;
COMMIT;
END TRY
BEGIN CATCH
ROLLBACK;
SET @status = 0; --change value of @status in the CATCH block
SET @message = ERROR_MESSAGE();--change value of @message in the CATCH block
END CATCH;
--show the value of each variable
SELECT @status AS 'Status',@message AS 'Message'
END;
答案 1 :(得分:0)
您是否尝试过使用RAISERROR()或THROW()?具体来说,使用严重性为11-19的RAISERROR()将强制执行跳转到CATCH块。详见https://docs.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql。
具体来看看例1:
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;