存储过程中的条件 WHERE 子句

mat*_*oss 6 sql sql-server sql-server-2008

这个问题可能归结为更简单的问题,但我仍然很好奇 SQL Server / TSQL 与条件WHERE子句的接近程度(以及它们不存在背后的推理也很有趣)。

我有一个存储过程,对于一些参数,它接受一个枚举数组(它已相应地转换为用户定义的表类型,它本质上模拟了一个 int 数组)。作为参考,数据类型如下:

CREATE TYPE myIntArray AS TABLE (
    val INT
);
Run Code Online (Sandbox Code Playgroud)

我的存储过程如下(修改为更简单):

CREATE PROCEDURE myProc
    @homeID INT,
    @name VARCHAR(500),
    @hometype_enum myIntArray READONLY,
    @country_enum myIntArray READONLY
AS
BEGIN
    SELECT * FROM my_table
    WHERE name=@name
END
GO
Run Code Online (Sandbox Code Playgroud)

我想要做的是根据作为 INT 表传入的枚举数组的值来过滤查询结果,IFF 它们甚至有传入的值(表可能为空)。伪代码看起来像这样:

SELECT * 
FROM my_table
WHERE name = @name
IF((SELECT COUNT(val) FROM @hometype_enum) > 0)
BEGIN
    AND hometype IN (SELECT val FROM hometype_enum)
END
IF((SELECT COUNT(val) FROM @country_enum ) > 0)
BEGIN
    AND country IN (SELECT val FROM country_enum )
END
Run Code Online (Sandbox Code Playgroud)

这两个枚举彼此独立,因此可以对没有枚举(两个表都为空)、非此即彼或两个枚举进行搜索和过滤。

我的实际查询涉及多个列、表和联合(我知道这很丑),所以它不如为每个场景复制/粘贴 3 行那么好SELECT。我目前正在使用一些相当丑陋的临时表逻辑,目前我将避免读者的注意。

除了弄清楚我的特定问题之外,我的主要问题是:SQL Server 是否支持条件WHERE子句语句(根据我的研究,我确信它不支持)?这是为什么(架构、时间复杂度、空间复杂度问题)?是否有任何或多或少简洁的方法来模拟条件子句,例如利用条件短路

感谢大家的见解。又是学习的一天!

M.A*_*Ali 5

正如评论中所建议的,处理这种条件 where 子句的最佳方法是使用动态 sql ..... 之类的东西......

CREATE PROCEDURE myProc
    @homeID INT,
    @name VARCHAR(500),
    @hometype_enum myIntArray READONLY,
    @country_enum myIntArray READONLY
AS
BEGIN
 SET NOCOUNT ON

 Declare @Sql NVarchar(MAX);

 SET @Sql = N' SELECT * FROM my_table '
          + N' WHERE name = @name '
           + CASE WHEN EXISTS (Select * FROM @hometype_enum)
             THEN N' AND hometype IN (SELECT val FROM hometype_enum) ' ELSE N' ' END
           + CASE WHEN EXISTS (Select * FROM @country_enum)
             THEN N' AND country IN (SELECT val FROM country_enum ) ' ELSE N' ' END

  Exec sp_executesql @Sql
                    ,N'@homeID INT , @name VARCHAR(500),
                      @hometype_enum myIntArray, @country_enum myIntArray'
                    ,@homeID
                    ,@name
                    ,@hometype_enum
                    ,@country_enum

END
GO
Run Code Online (Sandbox Code Playgroud)

使用sp_executesql将允许 sql server 存储同一存储过程的参数化执行计划。它是针对同一存储过程的不同参数集/组合的不同执行计划,以获得最佳性能。