0

我一直在优化查询,遇到了一个让我质疑我一直使用 SQL 的 OR 运算符的情况。(SQL Server 2000 也是)

我有一个查询,其中条件 (WHERE) 子句看起来像这样:

WHERE (Column1 = @Param1 or Column1 LIKE @Param1 + '%')
AND (@Param2 = '' OR Column2 = @Param2 OR Column2 LIKE @Param2 + '%')

现在,我一直理解 SQL 中的 OR 评估了这两个表达式。因此,所有对左侧表达式评估为 true 的记录将与所有在右侧表达式评估为 true 的记录一起返回。例如:

SELECT * FROM TABLE1
WHERE COL1 = 'Test' OR Col2 = 'Data'

这将返回 COL1 为“测试”的所有记录以及 Col2 为“数据”的任何记录

在上面的示例中,我将 Column2 条件修改为以下内容:

AND(Column2 LIKE ISNULL(@Param2, '') + '%')

突然间,我返回了 0 行。

我是否误认为 OR 只评估表达式,直到找到 TRUE 结果,或者是否存在会导致 2 个不同返回不同结果的条件?

4

4 回答 4

8

“OR 只计算表达式,直到找到 TRUE 结果”

它只需要,但这不是你的问题(实际上这是在你原来的情况下拯救你的原因)。您的两个查询并不真正等效。

我认为您NULL在 Column2 中有 s 永远不会导致(Column2 LIKE ISNULL(@Param2, '') + '%')为真 - 在您的原始版本中@Param2 = '',它掩盖了这种情况,因为它是真的(有时)

也许:

(ISNULL(Column2, '') LIKE ISNULL(@Param2, '') + '%')

记住 NULL 的三值逻辑:

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

但我不确定您的优化是否真的有帮助。

于 2009-01-23T18:28:56.010 回答
3

OR 并非包罗万象,尤其是在括号中。从那以后你所拥有的是:WHERE X AND Y。X 和 Y 本身是使用 OR 的布尔表达式这一事实并不重要:它们分别进行评估,然后将结果提供给 AND 运算符。

[编辑]:
再读一遍,我可能误解了你的问题。考虑到这一点,我将不得不选择另一个答案,因为NULL LIKE '%'返回 NULL,在这种情况下与 false 相同。你可以试试这个:

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'
于 2009-01-23T18:30:41.763 回答
1

仅供参考,您可以进行非常简单的实验,以了解并非所有条件都必须进行评估。

我在 Oracle 中这样做了,但我希望您在 SQL Server 中会得到类似的结果。

dev> select * from dual where 1=1 or 1/0 = 3;

D
-
X

OR 之后的条件必须没有被评估,因为它会引发被零除的错误。

这种对布尔运算符的处理通常被称为“短路”,AFAIK 在现代语言中是相当标准的。它也可以应用于 AND 表达式——如果第一个条件为假,则评估第二个条件没有意义,因为整个表达式不可能为 TRUE。

更多信息: http ://en.wikipedia.org/wiki/Short-circuit_evaluation

无论如何,正如凯德所说,你真正的问题可能是对 NULL 的错误处理。

于 2009-01-23T18:37:48.987 回答
0

MS-SQL 将首先评估左侧,除非需要,否则不会继续。

这与 AND 连接器相同,将评估左侧,如果为 false,则不评估右侧。

于 2009-01-23T18:33:59.027 回答