繁体   English   中英

T-SQL如何结束IF-ELSE IF-ELSE块

[英]T-SQL How to end an IF-ELSE IF-ELSE block

当我使用正确的参数运行以下过程以便不返回-1值时,我的DML语句都没有被触发。 我猜它是把我所有的DML语句都当作ELSE块的一部分。

SQL Server 2014

如何结束IF-ELSE-ELSE-IF块?

ALTER PROCEDURE [GenerateNumber] (
    @Code VARCHAR(2)
)
AS
BEGIN
    DECLARE @stringConcat VARCHAR = 'X';

    IF @Code = 'KP'
        SET @stringConcat += 'Y';
    ELSE IF @Code = 'RL'
        SET @stringConcat += 'Z';
    ElSE
        -- Return error code and stop processing
        SELECT -1;
        RETURN;

    BEGIN TRY
        -- Various DML statements...

        SELECT @successValue;
        RETURN;
    END TRY
    BEGIN CATCH
        SELECT -1;
        RETURN;
    END CATCH
END

好的,你必须在Else语句中使用BeginEnd ,因为它包含多行代码。

    IF @Code = 'KP'
        SET @stringConcat += 'Y';
    ELSE IF @Code = 'RL'
        SET @stringConcat += 'Z';
    ElSE
    Begin
        -- Return error code and stop processing
        SELECT -1;
        RETURN;
    End

你的缩进对你说谎。

IF @Code = 'KP'
     SET @stringConcat += 'Y';
 ELSE IF @Code = 'RL'
     SET @stringConcat += 'Z';
 ElSE
     -- Return error code and stop processing
     SELECT -1;  -- THIS is evaluated as the ELSE
     RETURN;     -- THIS is run regardless.

只有最后一个ELSE之后的第一行才会作为ELSE condidion执行。 RETURN将无论如何都会运行。 无法联系到您的BEGIN TRY。

试试这个:

IF @Code = 'KP'
     SET @stringConcat += 'Y';
 ELSE IF @Code = 'RL'
     SET @stringConcat += 'Z';
 ElSE
     BEGIN
     -- Return error code and stop processing
     SELECT -1;
     RETURN;
     END

如果您希望SELECT -1RETURN都在ELSE ,则必须使用BEGIN / END块。 现在只有SELECT -1在else分支内。

所以你需要

ELSE
  BEGIN
    SELECT -1;
    RETURN;
  END

If,ELSE IF,ELSE中的最后一个ELSE包含多行代码。 您需要使用BEGIN启动它并以END结束它。 有关更多详细信息,请参阅此MSDN文档

IF @Code = 'KP'
    SET @stringConcat += 'Y';
ELSE IF @Code = 'RL'
    SET @stringConcat += 'Z';
ElSE
    BEGIN
        -- Return error code and stop processing
        SELECT -1;
        RETURN;
    END

在您的情况下(双关语),您可能最好使用CASE WHEN构造,看到您想要评估@Code变量的不同值。 MSDN声明CASE适用于以下场景:

Evaluates a list of conditions and returns one of multiple possible result expressions.

我发现它使代码对于简单的评估更具可读性(但这很可能是个人偏好)。

您的代码最终看起来与此类似(伪代码。未经测试):

CASE @Code 
    WHEN 'KP' THEN SET @stringConcat += 'Y';
    WHEN 'RL' THEN SET @stringConcat += 'Z';
    ElSE
        -- Return error code and stop processing
        SELECT -1;
        RETURN;
END 

有关CASE声明的更多信息:

https://msdn.microsoft.com/en-us/library/ms181765.aspx

在您的示例中,RETURN始终运行。

从编码实践标准来看,我应该始终在SQL中使用BEGIN和END来清楚地说明逻辑块中的内容。 我更喜欢C#中的相同模式,即使不需要也可以使用大括号。 在我看来,缩进很重要,它可以轻松地跟踪它的开始和结束位置。

IF(1=2)
   BEGIN
      SELECT 1
   END
SELECT 2

IF(1=2) SELECT 1
   SELECT 2

这些在行为上是等效的,但第一个清楚地表明SELECT 1依赖于它上面的逻辑条件。

你真正想要的是:

IF @Code = 'KP'
    BEGIN
        SET @stringConcat += 'Y';
    END
ELSE IF @Code = 'RL'
    BEGIN
        SET @stringConcat += 'Z';
    END
ElSE
    BEGIN
        -- Return error code and stop processing
        SELECT -1;
        RETURN;
    END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM