在SQL查询中使用动态条件

如果我有一个使用可选参数运行搜索的查询,我通常的方法是将
NULL
传递给任何未使用的条件,并且有一个
WHERE
子句看起来像
WHERE (@Param IS NULL OR Field=@Param) AND (@Param2 IS NULL OR Field2=@Param2)
如果我的条件可能有点复杂,比如说
LIKE
条款,那么
SQL Server
会评估
IS NULL
然后将更复杂的条件短路吗?我是否可以在执行计划中查看是否存在?这种行为是否依赖于优化器选择的计划,这样我的开发和生产环境中的答案可能会有所不同(我有限制地查看生产中发生了什么,所以我希望行为一致) 。     
已邀请:
有关基于参数的查询的类似问题,请参阅此答案。 在他的回答中,他链接到一篇优秀的文章:Erland Sommarskog在T-SQL中的动态搜索条件     
我使用CASE语句。 所以你的是这样的:
WHERE (@Param IS NULL OR Field=@Param) AND (@Param2 IS NULL OR Field2=@Param2)
我会这样写:
WHERE CASE WHEN @Param IS NULL THEN 1 ELSE Field END = CASE WHEN @Param IS NULL THEN 1 ELSE @Param END AND  
CASE WHEN @Param2 IS NULL THEN 1 ELSE Field2 END = CASE WHEN @Param2 IS NULL THEN 1 ELSE @Param2 END
看看你得到的查询执行计划,在很多情况下,当你使用OR条件时,查询优化器使用表扫描。您也可以将'='替换为'like'等,实际上您甚至可以将其包含在case语句中。所以你可以用'8'替换'=' 希望这可以帮助。     
我发现了一个更实用的解决方案,可以避免使用动态SQL。 假设您有一个位字段,参数为1,0或(null = both)。然后使用以下SQL: 在哪里a.FIELD = CASN当ISNULL(@ PARAM,-1)= - 1然后a.FIELD ELSE @PARAM END 换句话说:如果你没有为@param提供一个明确的值,那么告诉A.field = a.field总是如此。如果是可空字段,则需要在该字段上应用ISNULL以避免null = null不通过。 示例:在INT字段上可以为null,
AND ISNULL(a.CALL_GENERAL_REQUIREMENTS,-1)=CASE WHEN ISNULL(@CALL_GENERAL_REQUIREMENTS,-2)=-2 THEN ISNULL(a.CALL_GENERAL_REQUIREMENTS,-1) ELSE @CALL_GENERAL_REQUIREMENTS END
如您所见,我将-2应用于参数@CALL_GENERAL_REQUIREMENTS的空值,这是因为选择的实数值可以是0(未传递),1(传递), - 1(尚未评估)。所以-2表示不选择此字段 可空字符串字段的示例:
AND ISNULL(a.CALL_RESULT,'')=CASE WHEN ISNULL(@CALL_RESULT,'')='' THEN ISNULL(a.CALL_RESULT,'') ELSE @CALL_RESULT END
所有这些都可以作为一种魅力,并且避免了使用串联创建动态SQL字符串时的大量麻烦,并且不需要分配特定权限来运行exec语句。 希望这能帮助任何人,因为它帮助了我。 祝你有美好的一天     

要回复问题请先登录注册