存储过程中的 IF THEN 循环

IF THEN loop in Stored Procedure

提问人:Michael 提问时间:4/13/2014 最后编辑:Michael 更新时间:4/14/2014 访问量:590

问:

我正在尝试在存储过程中使用 IF THEN 循环,如下所示:

@A varchar(100),
@B varchar(100)  
AS
BEGIN 

IF (@A = 'NULL' AND @B = 'NULL')
    BEGIN
    SELECT TOP 5 X1, X2, A, B, Y1, Y2, X3
        FROM mytable
    ORDER BY Y1 DESC
    SELECT TOP 5 X1, X2, A, B, Y1, Y2, X3
    FROM mytable
    ORDER BY Y2 DESC
    END

ELSE IF (@A = 'NULL' AND @B IS NOT NULL) 
    BEGIN
    SELECT TOP 5 Y1Rank, X1, X2, A, B, Y1, Y2, X3
    FROM (
            SELECT *,
        ROW_NUMBER() OVER (PARTITION BY B ORDER BY Y1 DESC) AS 'Y1Rank'
        FROM mytable
        WHERE B = @B
        ) b1

    SELECT TOP 5 Y2Rank, X1, X2, A, B, Y1, Y2, X3
    FROM (
        SELECT *,
        ROW_NUMBER() OVER (PARTITION BY B ORDER BY Y2 DESC) AS 'Y2Rank'
        FROM mytable
        WHERE B = @B
        ) b2
    END

ELSE IF (@A IS NOT NULL AND @B = 'NULL')
    BEGIN
    SELECT TOP 5 Y1Rank, X1, X2, A, B, Y1, Y2, X3
    FROM (
        SELECT *,
        ROW_NUMBER() OVER (PARTITION BY A ORDER BY Y1 DESC) AS 'Y1Rank'
        FROM mytable
        WHERE A = @A
        ) b3

    SELECT TOP 5 Y2Rank, X1, X2, A, B, Y1, Y2, X3
    FROM (
        SELECT *,
        ROW_NUMBER() OVER (PARTITION BY A ORDER BY Y2 DESC) AS 'Y2Rank'
        FROM mytable
        WHERE A = @A
        ) b4
    END
ELSE
    BEGIN
    SELECT TOP 5 Y1Rank, X1, X2, A, B, Y1, Y2, X3
    FROM (
        SELECT *,
        ROW_NUMBER() OVER (PARTITION BY A, B ORDER BY Y1 DESC) AS 'Y1Rank'
        FROM mytable
        WHERE A = @A AND B = @B
        ) b5

    SELECT TOP 5 Y2Rank, X1, X2, A, B, Y1, Y2, X3
    FROM (
        SELECT *,
        ROW_NUMBER() OVER (PARTITION BY A, B ORDER BY Y2 DESC) AS 'Y2Rank'
        FROM mytable
        WHERE A = @A AND B = @B
        ) b6
    END
END
GO

我的目标是让 SP 像搜索引擎一样工作:

  1. 如果用户同时指定@A和@B(例如,@A = alpha,@B = bravo),则它会返回 Y1 的前 5 个结果和 Y2 的前 5 个结果。这些结果以 A = alpha 和 B = bravo 表示。
  2. 如果用户仅指定 @A(例如,@A = alpha)或@B (@B = bravo)(另一个将输入为“NULL”),则它以 Y1 返回前 5 个结果,以 Y2 返回前 5 个结果。这些结果仅在 A=alpha 和任何 B 或 B=bravo 和任何 A 中。
  3. 如果用户未指定 A 和 B 中的任何一个(两者都输入为“NULL”),则它返回 Y1 的前 5 个结果和 Y2 的前 5 个结果。这些结果的 A 和 B 可以是任意值。

代码的实际结果是:

  • 如果我同时指定 A 和 B,则代码工作正常。
  • 如果我没有指定 A 或 B(输入 @A = 'NULL' 和 @B = 'NULL'),代码也可以正常工作。
  • 但是,如果我只指定 A 和 B 中的一个(例如,input @A = 'alpha' 和 @B = 'NULL';或者输入 A = 'NULL' 和 B = 'Bravo'),代码将仅返回一个带有标题的空表。

有没有人可以帮助我? 多谢。

=========================================================================================== 顺便说一句,我尝试在查询中使用相同的代码,但没有使用存储过程。 我试过了

DECLARE @A varchar(100),
@B varchar(100)
SET @A = 'NULL' 
SET @B = 'Bravo'

DECLARE @A varchar(100),
@B varchar(100)
SET @A = 'Alpha' 
SET @B = 'NULL'   

然后遵循的是我在存储过程中使用的完全相同的代码,它完全符合我的要求!我认为它们应该是等效的,但不知何故只在普通查询中起作用,而在存储过程中不起作用......我真的很困惑。

SQL SQL Server 存储过程 if-statement

评论

0赞 Michael 4/14/2014
问题解决了。我需要使其与 IS NULL/IS NOT NULL 保持一致,但不要像我编码的那样,同时使用 = 'NULL' 和 IS NOT NULL。
0赞 Michael 4/14/2014
我在代码中将 all = 'NULL' 更改为 IS NULL,现在它工作正常。

答:

0赞 shree.pat18 4/13/2014 #1

尝试对参数使用默认值,如下所示:

@A varchar(100) = 'NULL',
@B varchar(100) = 'NULL'

这样,如果用户只提供一个参数的值,另一个参数只需使用默认值。

评论

0赞 Michael 4/13/2014
谢谢你的建议。这将有助于用户体验,但无助于解决我输出中的问题。
0赞 shree.pat18 4/13/2014
如何称呼此存储过程?你传递什么参数?
0赞 Michael 4/14/2014
我正在传递@A并@B该程序。比如说,@A = 'alpha' 和 @B = 'Brova'
0赞 Daniel E. 4/14/2014 #2
declare @a as varchar(10)=NULL
if @a is null
SELECT @a as [a]

declare @b as varchar(10)='NULL'
if @b is null
SELECT @b as [b]

尝试上面的代码,不是一回事,你似乎已经混合和匹配了它们。is null='NULL'