Как отличаются операторы SQL "IS" и "="?

Я создаю несколько подготовленных операторов, которые используют параметризованные значения. В качестве примера:

SELECT * FROM "Foo" WHERE "Bar"[email protected]

Иногда @param может быть NULL. В таких случаях я хочу, чтобы запрос возвращал записи, где Bar - NULL, но указанный выше запрос этого не сделает. Я узнал, что для этого я могу использовать оператор IS. Другими словами:

SELECT * FROM "Foo" WHERE "Bar" IS @param

Помимо различной трактовки NULL, существуют ли другие способы, в которых эти два утверждения будут вести себя по-другому? Что, если @param не NULL, а вместо этого, скажем, 5? Использует ли оператор IS в этом случае безопасную (и нормальную) вещь? Есть ли другой подход, который я должен принять?

Ответ 1

Вам нужны записи из Foo, где Bar = @param, или если @param имеет значение null, где Bar - null. Некоторые из предлагаемых решений предоставят вам нулевые записи с помощью nonnull @param, который не похож на ваше требование.

Select * from Foo where (@param is null and Bar is null) or (Bar = @param)

Это не говорит о том, является ли это Oracle или SQL Server или другой РСУБД, поскольку каждый из них реализует несколько разные вспомогательные функции. SQL ISNULL (первый, второй), как NVL (первый, второй). Мне нравится SQL Server COALESCE() для общей применимости.

Сравнение ИС - только для нулевых сравнений.

Если вы используете SQL Server, и если вам действительно нужна другая таблица истинности 3VL для решения вашей проблемы (то есть, если у вас есть определенная потребность в "NULL = NULL" как "истина" в какой-то момент времени, а также признать, что это устарело и запрещает ваши причины, а не хорошая идея вообще), внутри вашего кода вы можете использовать директиву

SET ANSI_NULLS OFF

Здесь BOL на нем: http://msdn.microsoft.com/en-us/library/ms188048.aspx

Ответ 2

Вы можете подумать об этом неправильно. Если вы говорите о SQL Server, например (с тех пор, как я должен это сделать), ваш второй пример приведет к синтаксической ошибке. Значение в правой части IS не может быть 5.

Чтобы объяснить, рассмотрите объяснение MSDN этих двух операторов в T-SQL (обратите внимание, что вопрос о "SQL" и "SQL Server" не обязательно одинаков).

Оператор Equals (=)

Оператор IS NULL

Обратите внимание на что-то важное. В T-SQL нет оператора "IS". В частности, существует оператор <expression> IS [NOT] NULL, который сравнивает одно выражение с NULL.

Это не то же самое, что и оператор =, который сравнивает два выражения друг с другом и имеет определенное поведение, когда одно или оба выражения имеют значение NULL!

Ответ 3

Изменить: (Обновление от OP: это не делает то, что я. Если @param равно 5, то я хочу видеть только записи, где Bar - 5. Я хочу видеть записи, где Bar - NULL, если и только если @param - NULL. Приношу свои извинения, если мой вопрос не сделал этого ясно.)

В этом случае, я думаю, вы должны попробовать что-то вроде этого:

SELECT * FROM Foo WHERE [email protected] OR (Bar IS NULL AND @param IS NULL)

Предыдущая запись:

Почему бы просто не использовать OR?

SELECT * FROM "Foo" WHERE "Bar"[email protected] OR "Bar" IS NULL

В SQL Server вы можете использовать ISNULL:

SELECT * FROM "Foo" WHERE ISNULL("Bar",@param)[email protected]

Ответ 4

Я не знаю, какую версию SQL вы используете, но IS не имеет смысла в контексте, который вы только что описали. Я получаю синтаксическую ошибку, если я пытаюсь использовать ее так, как вы описали. Почему вы хотите использовать его в любом случае? Это обычное использование, и один из разработчиков программного обеспечения ожидает, что он найдет.

Ответ 5

Какую конкретную базу данных вы используете?

Если вы выполняете поиск на основе null (или не null), использование IS - это путь. Я не могу предоставить техническую причину, но я все время использую этот синтаксис.

SELECT * FROM Table WHERE Field IS NULL

SELECT * FROM Table WHERE Field IS NOT NULL