【问题标题】:IF THEN loop in Stored ProcedureIF THEN 在存储过程中循环
【发布时间】:2014-05-27 12:03:45
【问题描述】:

我正在尝试在存储过程中使用 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 个结果和前 5 个结果在 Y2 方面。这些结果仅在 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 之一(例如,输入 @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'   

接下来是我在存储过程中使用的完全相同的代码,它完全符合我的要求!我认为它们应该是等价的,但不知何故只适用于普通查询,但不适用于存储过程......我真的很困惑。

【问题讨论】:

  • 问题解决了。我需要保持它与 IS NULL/IS NOT NULL 一致,但不是,就像我编码的那样,一起使用 = ‘NULL’ 和 IS NOT NULL。
  • 我在代码中将 all = 'NULL' 更改为 IS NULL,现在它可以正常工作了。

标签: sql sql-server stored-procedures if-statement


【解决方案1】:

尝试为您的参数使用默认值,如下所示:

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

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

【讨论】:

  • 感谢您的建议。这将有助于用户体验,但无助于解决我输出中的问题。
  • 如何调用这个存储过程?你传递了什么参数?
  • 我将@A 和@B 传递给程序。比如说,@A = 'Alpha' 和 @B = 'Brova'
【解决方案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'不是同一个东西,你好像是混搭了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2021-11-17
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    相关资源
    最近更新 更多