我想知道是否有办法做这种查询(可选的where子句)而不对sql施加这样的负担。
SELECT *
FROM TABLE
WHERE
Name = IsNull(@Name,Name)
AND (
(@MinAge IS NULL AND @MaxAge IS NULL)
OR
(@MinAge IS NOT NULL AND @MaxAge IS NOT NULL AND Age BETWEEN @MinAge AND @MaxAge)
)
我知道我可以使用EXEC
将其作为变量执行,并在需要时包含查询,如下所示:
SET @sql = 'SELECT * FROM TABLE'
IF(@Name IS NOT NULL) SET @sql = @sql + ' WHERE Name = ''+@Name+'''
EXEC(@sql)
但我想避免这个选项^^^
我不知道SQL世界中的任何其他选项?
第一个查询会使SQL的负载成本超出所需的负担。
答案 0 :(得分:1)
Erland Sommarskog的这篇文章是我所知道的最广泛的资源 Dynamic Search Conditions in T‑SQL
答案 1 :(得分:0)
我认为你有三种可能的选择:
OPTION RECOMPILE
建议服务器在每次执行期间重新编译查询。它应该能够检测NULL值并相应地进行优化。 显然,缺点是每次执行时都要重新编译。
OPTIMIZE FOR
告诉服务器优化参数集的查询。在那里,您确实只有一个执行计划,但由于不幸的第一次查询,您不会冒更改的风险。
写两次
输入IF语句并进行两次查询。 如果您有许多参数,这当然不能很好地扩展......
答案 2 :(得分:0)
当您执行 BETWEEN 时,您不必检查 NOT NULL ,如果是@MinAge,它将无法通过该条件或者@MaxAge为空。换句话说,您可以按如下方式重写WHERE子句......
WHERE Name = IsNull(@Name,Name)
AND (
(@MinAge IS NULL AND @MaxAge IS NULL)
OR
(Age BETWEEN @MinAge AND @MaxAge)
)
我通常试图避免的另一个选项是使用if-else检查变量的状态,然后根据结果分支到两个单独的select语句中。换句话说......
IF @MinAge IS NULL AND @MaxAge IS NULL
SELECT <columnlist>
FROM TABLE
ELSE
SELECT <columnlist>
FROM TABLE
WHERE Age BETWEEN @MinAge AND @MaxAge