希望 Where 子句中的“存在”仅在传递的参数有值时使用

Posted

技术标签:

【中文标题】希望 Where 子句中的“存在”仅在传递的参数有值时使用【英文标题】:Want 'Exists' in a Where clause to be used only when passed parameter has a value 【发布时间】:2009-08-14 00:52:41 【问题描述】:

我在存储过程中有一个类似于下面的 Select(为简洁起见而缩写)。 @param 是存储过程的参数,可以为 NULL。

SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = @param AND ... AND ...) AND ... AND ...

我希望 EXISTS 语句(粗体部分)仅在 @param 有值时使用,否则忽略它。

如果可能,我不想使用动态 SQL 或临时表。我正在尝试使用 CASE 语句来处理 EXISTS 语句,但运气不佳。

【问题讨论】:

为了确保......“param”字段是否接受 NULL? 是的。我已经在我的问题中说明了这一点。 【参考方案1】:

在 WHERE 子句中使用 OR 很可能会非常缓慢,尤其是在 EXISTS 时。

其他选项...

联合:只有一个会返回行

SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = @param AND ... AND ...) AND ... AND ...
UNION ALL
SELECT name FROM Table1 WHERE @param IS NULL AND ... AND ...

条件分支:

IF @param2 IS NULL
    SELECT name FROM Table1 WHERE ... AND ...
ELSE
    SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = @param AND ... AND ...) AND ... AND ...

【讨论】:

【参考方案2】:
WHERE (@Param IS NULL OR EXISTS (SELECT .... ))

请注意,这并不能保证 - 查询优化器会做它想做的事。但是应该足够聪明以优化exists子句吗?

【讨论】:

那么您唯一需要注意的是存储过程将缓存第一个运行案例的执行计划;可能希望将存储过程标记为“WITH RECOMPILE” - 失去缓存执行计划的好处,但为每次调用获得最佳计划。 我在这里缺少什么?在本例中,如何仅在 @Param 有值时使用 EXISTS 语句? 当 param 有值时,该表达式的第一部分为 false,因此存在子句 运行。当 param 没有值时, where 表达式将始终返回 true,因此无需调用 EXISTS。唯一的问题是查询优化器是否足够聪明来实现这一点。

以上是关于希望 Where 子句中的“存在”仅在传递的参数有值时使用的主要内容,如果未能解决你的问题,请参考以下文章

Sql where 子句

游标 where 子句中的可选参数

始终选择表中所有记录的 WHERE 子句

具有另一个 sql 语句的 where 子句中的 case 条件

多个参数 psycopg2 where 子句 - 语法错误

选择不同的值,传递到 Where 子句