在存储过程中设置 RAISERROR 的编号和消息

Posted

技术标签:

【中文标题】在存储过程中设置 RAISERROR 的编号和消息【英文标题】:Set number and message for RAISERROR in stored procedure 【发布时间】:2012-11-07 07:04:02 【问题描述】:

我写了一个保存卡的存储过程。我想当Barcode_Num 重复时,不允许添加和显示消息(我知道必须从RAISERROR 使用),但我想设置RAISERROR 的数字并设置消息为:

卡号 10000001(ex) 是重复的,你不允许添加这个

我设置了这个但是没有用。

ALTER PROCEDURE  [dbo].[SaveCards]
    @Barcode_Num int
    ,@Card_Status_ID int 
    ,@Card_Type_ID int
    ,@SaveDate varchar(10)
    ,@Save_User_ID int 

AS
BEGIN
  BEGIN TRAN Entrance
    Begin Try 
    if (select COUNT(*) from TBL_Cards where Barcode_Num = @Barcode_Num ) = 0
    begin
    INSERT INTO [Parking].[dbo].[TBL_Cards]
               ([Barcode_Num]
               ,[Card_Status_ID]
               ,[Card_Type_ID]
               ,[Save_Date]        
               ,[Save_User_ID])

         VALUES
               (@Barcode_Num
               ,@Card_Status_ID
               ,@Card_Type_ID
               ,@SaveDate
               ,@Save_User_ID
               )
          end
             else
                 begin 
                 --
                 declare @EndCardID int ;
             set @EndCardID= (  select Barcode_Num  from TBL_Cards  WHERE TBL_Cards.Card_ID = (SELECT MAX(Card_ID)
                             FROM TBL_Cards  ))

                 declare @CardID int ;
                 set @CardID= ( select Barcode_Num  from TBL_Cards  where Barcode_Num = @Barcode_Num)

                    --RAISERROR('قبلا کارتی ب اين شماره ثبت شده است.',50000,1)
                RAISERROR((N'the card number %d is duplicate',@CardID),50000,1);
             end   
        COMMIT TRAN Entrance
        END TRY

        Begin CATCH
            ROLLBACK TRAN Entrance
            DECLARE @Error_Number   int
            SET @Error_Number = ERROR_NUMBER()
            DECLARE @Error_Message  varchar(max)
            SET @Error_Message = ERROR_MESSAGE()
            DECLARE @Log_Error_ID   int
            EXEC [LogError] @Error_Number, @Error_Message OUTPUT, @Log_Error_ID, @Save_User_ID

            IF @Error_Message IS NOT NULL
                RAISERROR(@Error_Message,16,1)
            ELSE
                RAISERROR((N'the card number %d is duplicate',@CardID),16,1)

            END CATCH   
    END 

    Begin CATCH
            ROLLBACK TRAN Entrance
            DECLARE @Error_Number   int
            SET @Error_Number = ERROR_NUMBER()
            DECLARE @Error_Message  varchar(max)
            SET @Error_Message = ERROR_MESSAGE()
            DECLARE @Log_Error_ID   int
            EXEC [LogError] @Error_Number, @Error_Message OUTPUT, @Log_Error_ID, @Save_User_ID

            IF @Error_Message IS NOT NULL
                RAISERROR(@Error_Message,16,1)
            ELSE
                RAISERROR('قبلا کارتی با اين شماره ثبت شده است',16,1)

            END CATCH   

    END  

【问题讨论】:

为什么你对Barcode_Num 没有唯一的约束?这将比您的代码更有效(并且还避免了您当前拥有的竞争条件) 因为我在 C# winform 中从用户那里得到了这个 这不是任何原因。只需在该列上创建一个唯一约束,SQL Server 就会为您管理它。然后,您可以捕获重复键错误,而不是引发您自己需要捕获的错误。 我的问题是别的 我的问题来自 RAISERROR 【参考方案1】:

如果您想使用RAISERRORs 格式化工具,参数位于严重性和状态参数之后:

RAISERROR('the card number %d is duplicate',16,1,@CardID)

【讨论】:

以上是关于在存储过程中设置 RAISERROR 的编号和消息的主要内容,如果未能解决你的问题,请参考以下文章

以后出现错误时,看不到预期的 PRINT 或 RAISERROR 输出

如何在存储过程 MySql 中设置默认时区

如何在 GitHub 和 Jenkins 中设置 DB2 存储过程

如何在存储过程中设置日期时间可选参数?

VB.Net 没有捕获存储过程 raiserror

SQL存储过程内部RaisError客户端抓不住弹不出错误的解决