【问题标题】:Stored Procedure If statement存储过程 If 语句
【发布时间】:2019-02-27 09:00:21
【问题描述】:

我想让 sp 使用条件参数,例如

CREATE PROCEDURE spTest
(
    @param1 DATE,
    @param2 DATE,
    @param3 NVARCHAR(8) = null
)

AS

IF (@param3 = 'test1')
BEGIN
    SELECT a, SUM(b) AS SumOfB, SUM(c) AS SumOfC FROM db1 GROUP BY a
END

WITH innerQuery1 AS
(
    SELECT a, b, c FROM db2 WHERE a >=@param1 AND a <= @param2
)
    SELECT a, SUM(b) AS SumOfB, SUM(c) AS SumOfC FROM innerQuery1 GROUP BY a

我知道这是非常通用的,但这个过程有效。我正在尝试做的是将条件“放在中间”,例如。

CREATE PROCEDURE spTest
(
    @param1 DATE,
    @param2 DATE,
    @param3 NVARCHAR(8) = null
)

AS

WITH innerQuery1 AS
(
    SELECT a, b, c FROM db2 WHERE a >=@param1 AND a <= @param2
)

IF (@param3 = 'test1')
BEGIN
    SELECT a, SUM(b) AS SumOfB, SUM(c) AS SumOfC FROM db1 GROUP BY a
END

    SELECT a, SUM(b) AS SumOfB, SUM(c) AS SumOfC FROM innerQuery1 GROUP BY a

现在它再也看不到 innerQuery1 了。 WITH 中不能有条件吗?

关于为什么它不起作用的任何想法?我的实际查询更长,嵌套更多。基本上尝试在这种情况下只拥有一个 sp 并使用基于参数的查询结果。

谢谢,

【问题讨论】:

  • WITHSELECT 的一部分。 IF 不是。您的第二个版本在语法上不正确。
  • 对于您问题中的第一个代码,第二个查询是否会运行@param3 = 'test1',您应该考虑使用ELSE,对于第二个代码它是不正确的。
  • 您可以使用明确的IF .. BEGIN END ELSE BEGIN .. END 块(并且可能复制WITH)或使用WITH ... SELECT ... WHERE @param3 = 'test1' UNION ALL SELECT ... WHERE @param3 IS NULL OR @param3 &lt;&gt; 'test1'。这两种方法都不是很优雅,但这对你来说是 T-SQL。如果您觉得拆分逻辑确实值得,请考虑使用表变量、临时表或表值参数。
  • 戈登,我很害怕,谢谢。
  • Jeroen,我的问题很简单。我试图避免重复内部查询。我会看看你的替代品。谢谢

标签: sql-server tsql stored-procedures parameters optional-parameters


【解决方案1】:

尝试将您的程序创建为:

CREATE PROCEDURE spTest
(
    @param1 DATE,
    @param2 DATE,
    @param3 NVARCHAR(8) = null
)

AS

IF (@param3 = 'test1')
BEGIN
    SELECT a, SUM(b) AS SumOfB, SUM(c) AS SumOfC FROM db1 GROUP BY a
END
    ELSE
        BEGIN
            WITH innerQuery1 AS
            (
                SELECT a, b, c FROM db2 WHERE a >=@param1 AND a <= @param2
            )
                SELECT a, SUM(b) AS SumOfB, SUM(c) AS SumOfC FROM innerQuery1 GROUP BY a;
        END
GO

【讨论】:

  • 萨米,谢谢。通过我的简单示例,我可以看到您的代码在哪里处理它。我的问题是我有 4 个嵌套查询,并且希望有条件地使用中间结果。另外,@param3 将有多个选项,而不是简单的 IF ELSE
【解决方案2】:

如果我理解您的意图,您可能想考虑一些不同的方法,例如将测试用例拆分为单独的 SP 并用它们组成测试套件:

CREATE PROC TestSuite_CheckAggregations
    @arg,
    @param1, @param2
as
  ...
  SET @testCase = CASE @arg 
     WHEN '1' THEN 'TestCase_1_innerQuery'
     WHEN '2' THEN `TestCase_2_DirectQuery`
  END
  ...
  EXEC @testCase
    @param1, @param2
  ...
END



CREATE PROC TestCase_1_innerQuery
...

CREATE PROC TestCase_2_DirectQuery
...

在自然支持此类事物的语言/框架上构建测试系统可能更有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 2015-04-22
    相关资源
    最近更新 更多