相当于SQL中的VB AndAlso?

Posted

技术标签:

【中文标题】相当于SQL中的VB AndAlso?【英文标题】:Equivalent to VB AndAlso in SQL? 【发布时间】:2010-12-11 13:51:57 【问题描述】:

在 SQL (SQL Server 2005) 中是否有等效于 VB 的 AndAlso/OrElse 和 C# 的 &&/||。我正在运行类似于以下内容的选择查询:

SELECT a,b,c,d
FROM table1
WHERE 
(@a IS NULL OR a = @a)
AND (@b IS NULL OR b = @b)
AND (@c IS NULL OR c = @c)
AND (@d IS NULL OR d = @d)

例如,如果 "@a" 参数作为 NULL 传入,则评估 WHERE 子句的第二部分 (a = @a) 没有意义。有没有办法通过使用特殊语法或重写查询来避免这种情况?

谢谢, 詹姆斯。

【问题讨论】:

【参考方案1】:

保证求值顺序的唯一方法是使用CASE

WHERE
   CASE
      WHEN @a IS NULL THEN 1
      WHEN a = @a THEN 1
      ELSE 0
   END = 1
   AND /*repeat*/

根据我的经验,这通常比让数据库引擎对其进行排序要慢。

TerrorAustralis 的答案通常是不可为空的列的最佳选择

【讨论】:

虽然通常较慢,但您可能有一个复杂的表达式作为第二种情况更快的表达式,在特殊情况下,第二部分甚至可能不计算(参见 MikeMuffinMan 的示例),所以在某些情况下,使用 CASE 的 andalso/orelse 方法是必须的。【参考方案2】:

试试这个:

AND a = ISNULL(@a,a)

这个函数查看@a。如果它不为 null,则等于表达式

AND a = @a

如果为null,则等于表达式

AND a = a 

(因为这总是正确的,所以它替换了@b is null 语句)

【讨论】:

人们应该谨慎使用这种方法,具体取决于实际查询。字段上的 IsNull 可能会阻止它使用索引。这里它在一个变量上,所以可能在这里工作,但一般要小心。 SQL 可以有效地将索引用于“b 为 null 或 b=@b”,但不能用于“Isnull(b,@b)=@b”。【参考方案3】:

查询引擎会为您解决这个问题。如您所写,您的查询很好。如果可以,所有运营商都会“短路”。

【讨论】:

不,他们不会。您不知道它们在 SQL 中的计算顺序。【参考方案4】:

另一种方法是:

IF (@a > 0) IF (@a = 5)
BEGIN

END

条件之后的另一个 if 将执行“AndAlso”逻辑。

我想强调这只是一种简短的写作方式:

IF (@a > 0) 
     IF (@a = 5)
     BEGIN

     END

【讨论】:

不幸的是,WHERE 子句中只有他 CASE 而不是 IF。但是在语句块中你是对的。【参考方案5】:

举个例子:

SELECT * FROM Orders
WHERE orderId LIKE '%[0-9]%' 
AND dbo.JobIsPending(OrderId) = 1 

Orders.OrderId 是 varchar(25)

dbo.JobIsPending(OrderId)带int参数的UDF

dbo.JobIsPending(OrderId) when Orders.OrderId NOT LIKE '%[0-9]%' 中的转换失败,所以没有短路

在 SQL Server 2008 R2 上测试

【讨论】:

以上是关于相当于SQL中的VB AndAlso?的主要内容,如果未能解决你的问题,请参考以下文章

Python 中的 AndAlso (&&) 和 OrElse (||) 逻辑运算符的等价物是啥?

为啥使用 And 而不是 AndAlso?

禁用 AND 和 OR 关键字

VB.Net 中的 SQL 语句错误

VB.Net 中的 SQL 查询

导出vs 2005(vb.net)中的所有sql表记录