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子句语句(根据我的研究,我确信它不支持)?这是为什么(架构、时间复杂度、空间复杂度问题)?是否有任何或多或少简洁的方法来模拟条件子句,例如利用条件短路?
感谢大家的见解。又是学习的一天!
正如评论中所建议的,处理这种条件 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 存储同一存储过程的参数化执行计划。它是针对同一存储过程的不同参数集/组合的不同执行计划,以获得最佳性能。
| 归档时间: |
|
| 查看次数: |
11705 次 |
| 最近记录: |