Чем отличаются операторы SQL «IS» и «=»? - PullRequest
14 голосов
/ 24 марта 2011

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

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

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

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

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

Ответы [ 5 ]

12 голосов
/ 24 марта 2011

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

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

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

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

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

SET ANSI_NULLS OFF

Вот BOL на нем: http://msdn.microsoft.com/en-us/library/ms188048.aspx

6 голосов
/ 24 марта 2011

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

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

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

Оператор IS NULL

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

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

6 голосов
/ 24 марта 2011

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

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

SELECT * FROM Foo WHERE Bar=@param OR (Bar IS NULL AND @param IS NULL)

Предыдущее сообщение:

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

SELECT * FROM "Foo" WHERE "Bar"=@param OR "Bar" IS NULL

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

SELECT * FROM "Foo" WHERE ISNULL("Bar",@param)=@param
3 голосов
/ 24 марта 2011

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

2 голосов
/ 24 марта 2011

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

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

SELECT * FROM Table WHERE Field IS NULL

SELECT * FROM Table WHERE Field IS NOT NULL
...