【问题标题】:IF ELSE in Stored Procedure - Syntax Issue?存储过程中的 IF ELSE - 语法问题?
【发布时间】:2016-07-06 13:21:56
【问题描述】:

由于某种原因,我无法为这个存储过程获得正确的语法。我有 2 个变量。问题是——当我们执行存储过程时,用户可能需要为参数提供 1 个整数、多个整数或无。我想在此过程中为用户提供所有选项,对于这两个参数。以下是我目前所拥有的。我一直在尝试不同的方法,看起来应该很容易解决。

现在,它似乎不喜欢 ELSE。我在“ELSE”一词附近得到了不正确的语法。当我取出这些时,我得到所有 4 个查询的结果窗口,即使其中只有 1 个 IF 可能为真。

谁能帮忙?

ALTER PROCEDURE sp_ProjectDocs_AuditDB_ByLB 
@BID VARCHAR = NULL, @LID VARCHAR = NULL
AS
BEGIN
    SET NOCOUNT ON

    --DECLARE @BID VARCHAR
    --, @LID VARCHAR 
    --SET @BID = '301,316,373,322,331'
    ----'301,316,373,322,331'
    --SET @LID = '1'
    ----'1,2,3,4'

    IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') = ''
        PRINT 'BOTH NULL'
        BEGIN
            SELECT VWPD.*
            FROM vw_ProjectDocs_AuditDB VWPD
        END
    ELSE
        IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') <> ''
            PRINT 'LID NULL'
            BEGIN
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD
                WHERE VWPD.LID IN (@LID)
            END
    ELSE        
        IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') = ''
            PRINT 'BID NULL'
            BEGIN
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD
                WHERE VWPD.BID IN (@BID)
            END
    ELSE
    --IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') <> ''
        PRINT 'NEITHER NULL'
        BEGIN
            SELECT VWPD.*
            FROM vw_ProjectDocs_AuditDB VWPD
            WHERE VWPD.LID IN (@LID) AND VWPD.BID IN (@BID)

        END
END
GO

--EXEC sp_ProjectDocs_AuditDB_ByLB '301','1'

GO

更新了 sql,以解决问题。这似乎可以运行,但我没有得到任何结果,当我可以通过将相同的参数直接传递给 select 语句中的视图进行验证时。

ALTER PROCEDURE sp_ProjectDocs_AuditDB_ByLB 
@BID VARCHAR = NULL, @LID VARCHAR = NULL
AS
BEGIN
    SET NOCOUNT ON

    --DECLARE @BID VARCHAR(100)
    --, @LID VARCHAR 
    --SET @BID = '301,316,373,322,331'
    ----'301,316,373,322,331'
    --SET @LID = '1'
    ----'1,2,3,4'

    IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') = ''
        BEGIN
            --PRINT 'BOTH NULL'
            SELECT VWPD.*
            FROM vw_ProjectDocs_AuditDB VWPD
        END
    ELSE
        IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') <> ''
            BEGIN
                --PRINT 'BID NULL'
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD
                WHERE VWPD.LID IN (@LID)
            END
    ELSE        
        IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') = ''
            BEGIN
                --PRINT 'LID NULL'
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD
                WHERE VWPD.BID IN (@BID)
            END
    ELSE
    --IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') <> ''
        BEGIN
            --PRINT 'NEITHER NULL'
            SELECT VWPD.*
            FROM vw_ProjectDocs_AuditDB VWPD
            WHERE VWPD.BID IN (@BID) AND VWPD.LID IN (@LID)

        END
END
GO

--EXEC sp_ProjectDocs_AuditDB_ByLB '301','1'

GO

【问题讨论】:

  • 除了逻辑错误之外,您还应该考虑重命名您的过程。 sp_ 前缀可能会导致一些性能问题。要么更改前缀,要么我的偏好是完全删除前缀。 sqlperformance.com/2012/10/t-sql-queries/sp_prefix
  • 我在这里注意到了其他几个潜在的问题。您已传入 varchars 但未指定大小。这意味着它们将默认为 30。通常最好是明确的。不过,更大的问题是您将这些 varchar 值与 IN 谓词一起使用。如果您要传递多个不起作用的值。此外,此过程可能存在性能问题,因为当生成的查询更改每次执行时,执行计划很容易混淆。 sqlinthewild.co.za/index.php/2009/09/15/…fwiw,我不是反对你的人
  • 谢谢你,肖恩!该默认 varchar 是我的问题的一部分。现在我只需要检测是否为参数传递了超过 1 个数字,因此我可以将它作为多列表传递给 IN where 子句。嗯....我有个主意!
  • 如果您需要多个值,您有几个选择(有些比其他更好)。我按优先顺序列出了这些。 1- 传入表值参数,2- 创建拆分器并解析值,3- 使用动态 sql。
  • 我想我想要#2。用户将拥有要传递的 ID 列表。他们最容易将逗号分隔的列表作为参数传递,然后让 proc 将其拆分到 in 语句中。我的轮子在转动大声笑

标签: sql-server if-statement stored-procedures null multiple-value


【解决方案1】:

您必须将PRINT 放入BEGIN/END 块中。

请注意,根据您的IF,消息'LID NULL''BID NULL' 不正确。

【讨论】:

    【解决方案2】:

    试试这个,你必须在Begin-End 块内给出Print 语句。

    ALTER PROCEDURE sp_ProjectDocs_AuditDB_ByLB 
    @BID VARCHAR = NULL, @LID VARCHAR = NULL
    AS
    BEGIN
        declare @sqlquery varchar(max)
    
        SET NOCOUNT ON
    
        --DECLARE @BID VARCHAR
        --, @LID VARCHAR 
        --SET @BID = '301,316,373,322,331'
        ----'301,316,373,322,331'
        --SET @LID = '1'
        ----'1,2,3,4'
    
        IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') = ''
    
            BEGIN
            set @sqlquery = '
            PRINT ''BOTH NULL''
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD'
            END
        ELSE
            IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') <> ''
    
                BEGIN
                set @sqlquery = '
                PRINT ''LID NULL''
                    SELECT VWPD.*
                    FROM vw_ProjectDocs_AuditDB VWPD
                    WHERE VWPD.LID IN(' + @LID+')'
                END
        ELSE        
            IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') = ''
    
                BEGIN
                set @sqlquery = '
                PRINT ''BID NULL''
                    SELECT VWPD.*
                    FROM vw_ProjectDocs_AuditDB VWPD
                    WHERE VWPD.BID IN ('+ @BID+')'
                END
        ELSE
        --IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') <> ''
    
            BEGIN
            set @sqlquery = '
            PRINT ''NEITHER NULL''
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD
                WHERE VWPD.LID IN ('+@LID+') AND VWPD.BID IN ('+@BID+')'
    
            END
        EXEC (@sqlquery)
    END
    GO
    

    【讨论】:

    • 这让我通过了 else 错误,但现在我没有得到任何结果,消息告诉我正确的“既不为空”。我可以使用我测试的参数(bid = 301,lid = 1)直接查询视图,我得到 10 个结果(我应该这样做)。但是从存储的过程中执行,我得到 0 个结果。有什么想法吗?
    • 你能不能把 PRINT 换成 SELECT 再试一次
    • 而不是 PRINT 'BID NULL',您只需尝试使用 SELECT 'BID NULL'
    • 但我需要的是带有传递参数的sql语句的结果。我可以试试,但这不是我想要做的。
    • 好的新东西要告诉你。我传递了参数'1','1',我得到了正确的结果,但是当我尝试'301','1'我得到0,视图中有10条记录,出价301和盖子1。不能找出为什么它没有得到正确的结果。当我需要为 1 个参数(通常是 BID)传递逗号分隔列表时,我什至不确定这是否可行。
    【解决方案3】:

    这是最终的工作存储过程。

    ALTER PROCEDURE sp_ProjectDocs_AuditDB_ByLB 
    @BID NVARCHAR(500) = NULL, @LID NVARCHAR(500) = NULL
    AS
    BEGIN
        SET NOCOUNT ON
    
        --DECLARE @BID NVARCHAR(500)
        --, @LID NVARCHAR(500)
        --SET @BID = '301,316,373,322,331'
        ----'301,316,373,322,331'
        --SET @LID = '1'
        ----'1,2,3,4'
    
    
        IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') = ''
            BEGIN
                --PRINT 'BOTH NULL'
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD
            END
        ELSE
            IF ISNULL(@BID,'') = '' AND ISNULL(@LID,'') <> ''
                BEGIN
                    --PRINT 'BID NULL'
                    SELECT VWPD.*
                    FROM vw_ProjectDocs_AuditDB VWPD
                    WHERE VWPD.LID IN (SELECT * FROM SPLIT(@LID, ','))
                END
        ELSE        
            IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') = ''
                BEGIN
                    --PRINT 'LID NULL'
                    SELECT VWPD.*
                    FROM vw_ProjectDocs_AuditDB VWPD
                    WHERE VWPD.BID IN (SELECT * FROM SPLIT(@BID, ','))
                END
        ELSE
        --IF ISNULL(@BID,'') <> '' AND ISNULL(@LID,'') <> ''
            BEGIN
                --PRINT 'NEITHER NULL'
                SELECT VWPD.*
                FROM vw_ProjectDocs_AuditDB VWPD
                WHERE VWPD.BID IN (SELECT * FROM SPLIT(@BID, ',')) AND VWPD.LID IN (SELECT * FROM SPLIT(@LID, ','))
    
            END
    END
    GO
    
    --EXEC sp_ProjectDocs_AuditDB_ByLB '301','1'
    
    GO
    

    【讨论】:

      猜你喜欢
      • 2018-05-23
      • 2021-05-22
      • 2010-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-18
      • 2016-11-09
      相关资源
      最近更新 更多