T-SQL 基本自定义错误在存储过程中被忽略

T-SQL Basic custom errors get ignored in stored procedure

编辑 3:解决方案 显然我的代码在 BEGIN / END 块上有问题,正如回复的用户建议的那样(谢谢!)

仍然,我无法让它工作,直到我找到这个 post 并尝试了这个 if/else 结构:using Switch like logic in T-SQL


编辑 2:
我在程序中写了几个 PRINTs,值传递得恰到好处。现在它只说 'Invalid ID',即使在发送 200 时也是如此。

220
dsf4
Oct 12 2018 10:10AM
Msg 50000, Level 16, State 1, Procedure p_ValCulture, Line 188
Invalid ID

编辑: 我试过在 BEGIN / END 中设置错误信息;它没有用。这是该部分的代码。

IF @operacion LIKE 'I'
    BEGIN
        IF @id IS NULL OR @id <= 0
            BEGIN
                SELECT @errorDesc = 'Invalid ID'    
                RAISERROR(@errorDesc, 16, 1)
            END

        IF EXISTS(SELECT 1 FROM Production.Culture AS pc WHERE PC.CultureID = @id)
            BEGIN   
                SELECT @errorDesc = 'ID already exists'
                RAISERROR(@errorDesc, 16, 1)
            END
END

如果我执行存储过程就会得到这个

Msg 50000, Level 16, State 1, Procedure p_ValCulture4, Line 183

该消息下方有一个空白 space,这是我无法设置的错误消息的值。

这些是我传递的参数:

GO
EXEC p_ValCulture4 200, 'John', '10-12-2018 10:10:10.000','I'

我在 Windows 64 位上使用 SQL Server Management 2014。


我正在努力赶上一些 T-SQL 我没有得到足够的关注..但我完全被困住了:/我已经检查了 Google, Youtube,所以,等等。尝试了很多东西,但没有任何效果,我浪费时间完全停留在我无法理解的这一部分上。

我有一个存储过程,当发送 'operation' 作为 'I' (char) 时,将执行插入 table。我正在使用 AdventureWorks2014 数据库作为练习。

问题是如果发送的 id 为空,我想发送不同的错误消息,或者如果它已经存在于 table 中,我想发送另一个错误消息,等等。这是该过程的代码:

CREATE PROCEDURE p_ValCulture4
   @id INT,
   @name NVARCHAR(50),
   @date DATETIME,
   @operacion CHAR(1)
AS
BEGIN
   print @id
   print @name
   print @date
   SET NOCOUNT ON 
   DECLARE @errorDesc nvarchar(MAX)

   BEGIN TRY

       SELECT @operacion = UPPER(@operacion) 

       IF @operacion = 'I'  /* the Insert option */
          BEGIN
              IF @id IS NULL OR @id <= 0
                  BEGIN
                      SELECT @errorDesc = 'Invalid ID'  
                      RAISERROR(@errorDesc, 16, 1)
                  END

              IF EXISTS(SELECT 1 FROM Production.Culture AS pc WHERE PC.CultureID = @id)
                 BEGIN
                      SELECT @errorDesc = 'ID already exists'
                      RAISERROR(@errorDesc, 16, 1)
                 END

              SELECT @errorDesc = 'ERROR: Insert error'
              INSERT INTO Production.Culture VALUES
        (@id, @name, @date);
              SELECT 'Rows: ' + CONVERT(VARCHAR(10),@@ROWCOUNT)
          END
      END TRY
   BEGIN CATCH
       RAISERROR (@errorDesc,16,1)
   END CATCH
END

第一个 IF,如果我发送 id = null 工作正常,我得到正确的错误;但是如果我发送一个现有的 id,IF 就会被完全忽略。插入也会发生同样的情况,它工作正常,但前提是过程中没有 IFs..

我不明白这些 IF - BEGIN / END 是如何工作的..以及为什么它只能读取第一个 IF 而忽略后续的..

我试过将所有内容都放在 IF - BEGIN / END 和 ELSE - BEGIN / END 中,结果相同。

我试过在 de IF 内部和外部设置错误消息。此外,在 IF 内部,但在 BEGIN 之前。我试过直接在RAISERROR里面写错误,结果一样。

如果有人能帮助我理解为什么 IF 被忽略以及 T-SQL 中这些 IF 背后的逻辑,我将不胜感激 :) 谢谢!

一致的缩进肯定会帮助您解决与 Begin End 对相关的问题。

您的第一个 IF 测试的 BEGIN 位于其下方的同一水平位置,但下一个 IF 测试的 BEGIN 进一步缩进。

如果您像第一个一样进行此 IF 测试,因为 BEGIN 和 END 位于相同的水平位置,它将暴露 ZLK 在上述评论中指出的问题,SELECT @errorDesc = 'Invalid ID' 在 BEGIN END 对之外 运行。