Подтвердить что ты не робот

Isnull vs имеет значение null

Я заметил, что ряд запросов на работе и на SO используют ограничения в форме:

isnull(name,'') <> ''

Есть ли какая-то особая причина, почему люди делают это, а не более тонкие

name is not null

Это проблема устаревания или производительности?

4b9b3361

Ответ 1

where isnull(name,'') <> ''

эквивалентно

where name is not null and name <> '' 

что, в свою очередь, эквивалентно

where name <> ''

(если имя IS NULL, окончательное выражение будет оцениваться неизвестным и строка не возвращается)

Использование шаблона ISNULL приведет к сканированию и будет менее эффективным, как видно из приведенного ниже теста.

SELECT ca.[name],
       [number],
       [type],
       [low],
       [high],
       [status]
INTO   TestTable
FROM   [master].[dbo].[spt_values]
       CROSS APPLY (SELECT [name]
                    UNION ALL
                    SELECT ''
                    UNION ALL
                    SELECT NULL) ca 


CREATE NONCLUSTERED INDEX IX_TestTable ON dbo.TestTable(name)

GO


SELECT name FROM TestTable WHERE isnull(name,'') <> ''

SELECT name FROM TestTable WHERE name is not null and name <> ''
/*Can be simplified to just WHERE name <> '' */

Что должно дать вам план выполнения, который вам нужен.

введите описание изображения здесь

Ответ 2

is not null

Будет проверять, не поле не пустое. Если поле содержит пустую строку, то поле больше не равно null.

isnull(name, '') <> name

Проверяет как пустую, так и пустую строку.

Ответ 3

isnull(name,'') <> :name является сокращением для (name is null or name <> :name) (предполагая, что :name никогда не содержит пустую строку, поэтому почему подобные сокращения могут быть плохими). ​​

По производительности, это зависит. Операторы or в предложениях where могут дать очень плохую производительность. Однако функции на столбцах ухудшают использование индекса. Как обычно: профиль.

Ответ 4

isnull(name,'') <> name

Ну, я вижу, что они используют это, потому что этот путь, если имя не соответствует или равно null, возвращает его как неудачное сравнение. Это действительно означает: name is null или name <> name

Где, как этот name is not null, просто проверяет, имеет ли имя значение null.

Ответ 5

Они не означают одно и то же.

name is not null 

Это проверяет записи, где поле имени равно null

isnull(name,'') <> name  

Это изменяет значение нулевых полей на пустую строку, чтобы их можно было использовать в сравнении. В SQL Server (но не в Oracle, я думаю), если значение равно null, и оно используется для сравнения эквалайзера или неравенства, это не будет считаться, потому что null означает, что я не знаю значения и, следовательно, не является фактическим значением. Поэтому, если вы хотите убедиться, что при сопоставлении учитываются нулевые записи, вам нужны ISNULL или COALESCE (который является термином ASCII STANDARD для использования в качестве ISNULL doen't во всех базах данных).

То, что вы должны смотреть, это differnece между

isnull(a.name,'') <> b.name  

a.name < > b.name

тогда вы поймете, почему ISNULL необходим для получения правильных результатов.

Ответ 6

Я, по-видимому, неправильно понял ваш вопрос. Поэтому позвольте мне нанести свой первый ответ и попробовать следующее:

isnull(name,'') <> ''

является ошибочным ярлыком для

name is not null and name <> ''

Ответ 7

Другие указали на функциональную разницу. Что касается проблемы производительности, в Postgres я обнаружил, что - о, я должен упомянуть, что Postgres имеет функцию "coalesce", которая эквивалентна "isnull", найденной в некоторых других диалектах SQL, но в Postgres, говоря

where coalesce(foobar,'')=''

значительно быстрее, чем

where foobar is null or foobar=''

Кроме того, может быть намного быстрее сказать

 where foobar>''

над

where foobar!=''

Больше, чем тест, может использовать индекс и, таким образом, пропускать все пробелы, в то время как тест не равный должен делать полный просмотр файла. (Предполагая, что у вас есть индекс в поле, и ни один другой индекс не используется в предпочтении.)

Ответ 8

Также, если вы хотите использовать индекс в этом столбце, используйте

name is not null and name <> '' 

Ответ 9

Эти два запроса не совпадают. Например, у меня нет среднего имени, это известный факт, который можно сохранить как

MiddleName=''

Однако, если мы не знаем кого-то среднего имени, мы можем хранить NULL. Таким образом, ISNULL (MiddleName, '') означает "лица без известных средних имен".

Ответ 10

Он должен обрабатывать как пустую строку, так и NULL. Хотя хорошо иметь возможность иметь дело с одним утверждением, isnull является проприетарным синтаксисом. Я бы написал это с помощью переносного стандартного SQL как

NULLIF(name, '') IS NOT NULL