Оператор SQL «Или». Как это работает в следующем сценарии? - PullRequest
0 голосов
/ 23 января 2009

Я работал над оптимизацией запроса и столкнулся с ситуацией, которая заставляет меня задаться вопросом, как я всегда использовал оператор ИЛИ SQL. (SQL Server 2000 также)

У меня есть запрос, где условное (WHERE) предложение выглядит примерно так:

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

Теперь я всегда понимал, что OR в SQL вычисляет оба выражения. Таким образом, все записи, которые оценили true для левого выражения, будут возвращены вместе со всеми записями, которые оценили true в правом выражении. Например:

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

Это вернет все записи, где COL1 - «Тест», а также любую запись, где Col2 - «Данные»

В приведенном выше примере я изменил условное выражение Column2 следующим образом:

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

Внезапно я вернул 0 строк.

Я ошибался в том, что ИЛИ только оценивает выражения, пока не найдет ИСТИННЫЙ результат, или есть условие, которое заставит 2 разных вернуть разные результаты?

Ответы [ 4 ]

8 голосов
/ 23 января 2009

"ИЛИ вычисляет только выражения, пока не найдет ИСТИННЫЙ результат"

Это только нужно, но это не ваша проблема (на самом деле это то, что спасло вас в вашем первоначальном случае). Ваши два запроса на самом деле не эквивалентны.

Я думаю, у вас есть NULL s в столбце 2, что никогда не приведет к истине (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

Но я не уверен, что ваша оптимизация действительно помогает.

3 голосов
/ 23 января 2009

ИЛИ не является всеобъемлющим, особенно в скобках. То, что вы имеете в большем, так это: WHERE X AND Y. Тот факт, что X и Y сами являются логическими выражениями, в которых используется OR, не важен: они оцениваются отдельно, а затем результаты передаются оператору AND.

[править]:
Читая еще раз, я, возможно, неправильно понял ваш вопрос. Имея это в виду, мне придется пойти с другим ответом, потому что NULL LIKE '%' возвращает NULL, что в данном случае совпадает с false. Вы можете попробовать это вместо этого:

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'
1 голос
/ 23 января 2009

К вашему сведению, вы можете провести очень простые эксперименты, чтобы убедиться, что не все условия обязательно оценены.

Я сделал это в Oracle, но я ожидаю, что у вас будет аналогичный результат в SQL Server.

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

D
-
X

Условие после ИЛИ не должно оцениваться, так как это приведет к ошибке деления на ноль.

Эта обработка булевых операторов обычно известна как «короткое замыкание» и, AFAIK, является довольно стандартной в современных языках. Это также может применяться в выражении AND - если первое условие ложно, нет смысла оценивать второе условие, поскольку все выражение не может быть ИСТИНА.

Подробнее: http://en.wikipedia.org/wiki/Short-circuit_evaluation

В любом случае, как сказал Кейд, ваша настоящая проблема, вероятно, в неправильном обращении с NULL.

0 голосов
/ 23 января 2009

MS-SQL сначала оценит левую часть и не будет продолжать, если в этом нет необходимости.

То же самое относится и к разъему AND, левая сторона будет оценена, а если false, то правое не будет оцениваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...