存储过程用于显示 table 变量在另一个存储过程中不起作用的错误

Stored procedure is used to show the error in a table variable is not working inside another stored procedure

我有一个结构如下的存储过程

CREATE PROCEDIRE Newprice   
    (@a VARCHAR(10),
     @b MONEY,
     @c MONEY)
AS
BEGIN
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

    BEGIN TRANSACTION priceS
        IF EXISTS (SELECT * 
                   FROM [dbo].[prices]
                   WHERE a = @a)    
        BEGIN TRY
            UPDATE DBO.prices
            SET OpenPrice = @b, ClosePrice = @c
            WHERE a = @a

            PRINT 'Price has been updated'
        END TRY
        BEGIN CATCH
            EXEC [dbo].[err]
        END CATCH
    ELSE
        PRINT 'No update needed'
                        
    COMMIT TRANSACTION priceS
END

这个存储过程 运行 很好,但它没有显示我创建的 table 来显示 [dbo].[err] 存储过程中的错误。

查询如下

ALTER PROCEDURE [dbo].[err]
AS
BEGIN
    DECLARE @errnum INT,
            @severity INT,
            @errstate INT,

    SET @errnum = ERROR_NUMBER()
    SET @severity = ERROR_SEVERITY()
    SET @errstate = ERROR_STATE()

    DECLARE @Erro_Handler TABLE     
                          (
                              errnum    int,
                              severity  int,
                              errstate  int,
                          ) 

    INSERT INTO @Erro_Handler (errnum, severity, errstate)
    VALUES (@errnum, @severity, @errstate)

    SELECT *
    FROM @Erro_Handler
END

如您所见,最后一部分是查看 table 变量,该变量以 table 格式显示错误,但每当我尝试通过添加错误的数据类型来调用此存储过程时,它不会调用,而是显示常规错误消息。我在另一个例子上试过了,效果很好

供您参考,示例如下:

BEGIN TRY
   DECLARE @x int
   SELECT @x = 1/0
   PRINT 'Not reached'
END TRY
BEGIN CATCH 
   EXEC [dbo].[err]
END CATCH

如果您只是想显示错误,为什么不试试这个呢?

BEGIN TRY

   DECLARE @x int;
   SELECT @x = 1/0;
   PRINT 'Not reached';

END TRY
BEGIN CATCH 
   
    SELECT 
        ERROR_NUMBER() AS ErrNum, 
        ERROR_MESSAGE() AS ErrMsg, 
        ERROR_STATE() AS ErrState, 
        ERROR_SEVERITY() AS ErrSeverity;

END CATCH

Returns

+--------+-----------------------------------+----------+-------------+
| ErrNum |              ErrMsg               | ErrState | ErrSeverity |
+--------+-----------------------------------+----------+-------------+
|   8134 | Divide by zero error encountered. |        1 |          16 |
+--------+-----------------------------------+----------+-------------+

您可以修改以下存储过程。它会如您所愿地工作。

希望对朋友有帮助:))

create table Test(ID int, Amount decimal, Account varchar(20), Date datetime)

-------
insert into Test
values(1, 6000, 'G500', '2020-02-20'),
(1, 6000, 'D800', '2020-02-20'),
(2, 50, 'A950', '2019-08-20'),
(2, 50, 'H650', '2019-08-20')

-------
Create PROCEDURE [dbo].[err]
AS
BEGIN
DECLARE @errnum INT,
        @severity INT,
        @errstate INT

SET     @errnum = ERROR_NUMBER()
SET     @severity = ERROR_SEVERITY()
SET     @errstate = ERROR_STATE()


DECLARE @Erro_Handler TABLE(
                                    errnum      int,
                                    severity    int,
                                    errstate    int
                                    
                           )
INSERT INTO @Erro_Handler   ( errnum,severity , errstate )
VALUES                      ( @errnum,@severity ,@errstate )

SELECT  *
FROM    @Erro_Handler
END

---------------------
Alter PROC     Newprice    (
                                        @a  int,
                                        @b varchar(20)
                                        )
AS
BEGIN
            SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
            BEGIN TRY
                BEGIN TRANSACTION                       
                    IF EXISTS       (
                                    SELECT  * 
                                    FROM    [dbo].Test
                                    WHERE   ID = @a
                                    )   
                        BEGIN   
                                UPDATE      Test
                                SET         Amount = @b
                                WHERE       ID = @a
                                PRINT   'price Has Been Updated'                                 
                        END
                    ELSE
                        PRINT   'no update needed'   
                COMMIT TRANSACTION
            END TRY                                     
                        BEGIN CATCH
                              EXEC [dbo].[err]                                  
                            IF (XACT_STATE()) = -1  
                            BEGIN  
                                PRINT  N'The transaction is in an uncommittable state.' +  
                                        'Rolling back transaction.'  
                                ROLLBACK TRANSACTION;  
                            END;  
        
                            -- Test if the transaction is committable.  
                            IF (XACT_STATE()) = 1  
                            BEGIN  
                                PRINT N'The transaction is committable.' +  
                                    'Committing transaction.'  
                                COMMIT TRANSACTION;     
                            END;  
                        END CATCH                                           
            
END

----
Exec Newprice 1, 'hello'