如果第二个记录集成功,如何选择两个记录集?

时间:2017-07-23 17:47:58

标签: sql-server stored-procedures transactions

我将在发送准备好的记录集之前使用简单的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;

如果第二个语句成功,首先如何选择语句?

2 个答案:

答案 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;