Сравнение с NULL в SQL - PullRequest
       26

Сравнение с NULL в SQL

6 голосов
/ 10 сентября 2011

ANSI-92 SQL-мандаты, которые сравниваются с NULL, оцениваются как "ложные", например:

SELECT * FROM table WHERE field = NULL
SELECT * FROM table WHERE field != NULL

Будет оба не возвращать строк, потому что NULL нельзя сравнивать подобным образом. Вместо этого следует использовать предикаты IS NULL и IS NOT NULL:

SELECT * FROM table WHERE field IS NULL
SELECT * FROM table WHERE field IS NOT NULL

Исследования показали, что Oracle 1 , PostgreSQL, MySQL и SQLite поддерживают синтаксис ANSI. Добавьте к этому списку DB2 и Firebird.

Помимо SQL Server с выключенным ANSI_NULLS, какие другие СУБД поддерживают синтаксис не-ANSI?

1 Вся пустая строка = NULL несмотря на беспорядок.

Ответы [ 2 ]

15 голосов
/ 10 сентября 2011

Для чего бы то ни было, сравнение чего-либо с NULL не является строго ложным, это неизвестно . Кроме того, NOT неизвестно до сих пор неизвестно.

ANSI SQL-99 определяет предикат IS [NOT] DISTINCT FROM. Это позволяет смешивать нулевые и ненулевые значения в сочетаниях и всегда получать значение true или false. Нулевой по сравнению с нулевым, таким образом, является истинным, в противном случае любой ненулевой по сравнению с нулевым является ложным. Так что отрицание работает так, как вы, вероятно, ожидаете.

PostgreSQL, IBM DB2 и Firebird поддерживают IS [NOT] DISTINCT FROM.

MySQL имеет аналогичный нулевой безопасный оператор сравнения <=>, который возвращает истину, если операнды одинаковы, и ложь, если они разные.

У Oracle самый сложный путь. Вы должны проявить творческий подход, используя NVL() или логические выражения:

WHERE a = b OR (a IS NULL AND b IS NULL)

Тьфу.

3 голосов
/ 10 сентября 2011

Здесь - хорошее сравнение обработки нулей в SQLite, PostgreSQL, Oracle, Informix, DB2, MS-SQL, OCELOT, MySQL 3.23.41, MySQL 4.0.16, Firebird, SQL Anywhere иBorland Interbase

...