Эквивалентно VB и тоже в SQL? - PullRequest
4 голосов
/ 30 октября 2009

Есть ли эквивалент SQL * VB AndAlso / OrElse и C # && / || в SQL (SQL Server 2005). Я выполняю запрос на выборку, подобный следующему:

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, нет смысла оценивать 2-ю часть предложения WHERE (a = @a). Есть ли способ избежать этого, используя специальный синтаксис или переписав запрос?

Спасибо, Джеймс.

Ответы [ 5 ]

5 голосов
/ 18 июля 2010

Единственный способ гарантировать порядок оценки - использовать CASE

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

По моему опыту, это обычно медленнее, чем просто дать машине БД разобраться с этим.

Ответ TerrorAustralis, как правило, является наилучшим вариантом для столбцов, которые не могут быть обнулены

3 голосов
/ 30 октября 2009

Попробуйте это:

AND a = ISNULL(@a,a)

Эта функция смотрит на @a. Если оно не равно нулю, оно равняется выражению

AND a = @a

Если оно равно нулю, оно равно выражению

AND a = a 

(поскольку это всегда так, оно заменяет оператор @b is null)

1 голос
/ 30 октября 2009

Механизм запросов позаботится об этом за вас. Ваш запрос, как написано, в порядке. Все операторы будут "замыкать", если могут.

0 голосов
/ 16 февраля 2014

Возьмите этот пример:

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

Orders.OrderId является varchar (25)

dbo.JobIsPending(OrderId) UDF с параметром int

Нет короткого замыкания, так как преобразование не выполняется в dbo.JobIsPending(OrderId) when Orders.OrderId NOT LIKE '%[0-9]%'

протестировано на SQL Server 2008 R2

0 голосов
/ 02 февраля 2014

Другой способ сделать:

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

END

Другое, если после условия будет выполняться логика «AndAlso».

Я хочу подчеркнуть, что это всего лишь короткий способ написать:

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

     END
...