【问题标题】:Equivalent to VB AndAlso in SQL?相当于SQL中的VB AndAlso?
【发布时间】: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) 没有意义。有没有办法通过使用特殊语法或重写查询来避免这种情况?

谢谢, 詹姆斯。

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql short-circuiting


    【解决方案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 上测试

    【讨论】:

      猜你喜欢
      • 2022-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多