Использование обнуляемых столбцов в предложении WHERE

Предположим определение таблицы в SQL Server следующим образом:

CREATE TABLE MyTable (
  Id   UNIQUEIDENTIFIER NULL,
  Info VARCHAR(MAX)
)

И запрос:

DECLARE @id UNIQUEIDENTIFIER
DECLARE @info VARCHAR(MAX)
IF @id IS NOT NULL
BEGIN
  SELECT @info = Info
    FROM MyTable
    WHERE Id = @id
END

В этом случае статический анализатор кода Visual Studio выдает следующую ошибку:

Предупреждение: SR0007: Microsoft.Performance: столбцы со значениями Nullable могут привести к тому, что окончательные результаты будут оцениваться как NULL для предиката.

Я не вижу здесь проблемы. Ошибка связана с производительностью; MSDN говорит, что я должен использовать ISNULL() - но сравнение с NULL всегда равно false, верно? Я что-то упустил, или предупреждение просто неправильно?

6 ответов

Решение

Я думаю, что это относится к предложению WHERE. Это говорит о том, что и ваш параметр, и ваш столбец могут иметь значение NULL, и в этом случае ваше предложение WHERE больше не оценивается как true/false. Путем направления столбца, который может быть пустым, в столбец, для которого всегда определено значение (через ISNULL), вы будете в лучшей форме с точки зрения логики.

Вот документация Microsoft об этой ошибке.

Кроме того, значения NULL предположительно делают запросы медленнее.

Я думаю, что это ложное предупреждение - вы можете подавить его в каждом конкретном случае или это конкретное предупреждение полностью?

Что происходит, когда вы делаете это?

CREATE TABLE MyTable (
  Id   UNIQUEIDENTIFIER NOT NULL,
  Info VARCHAR(MAX)
)

Я думаю, что анализатор может просто не учитывать ваше утверждение IF.

Ваш код кажется мне правильным.

Нулевое сравнение зависит от настройки.

When SET ANSI_NULLS is ON, all comparisons against a null value evaluate to UNKNOWN

When SET ANSI_NULLS is ON, a SELECT statement that uses WHERE column_name = NULL returns zero rows even if there are null values in column_name. A SELECT statement that uses WHERE column_name <> NULL returns zero rows even if there are no nnull values in column_name.

When SET ANSI_NULLS is OFF, the Equals (=) and Not Equal To (<>) comparison operators do not follow the ISO standard.

Это отсюда.

IF @id IS NOT NULL

следует заменить на

IF ISNull(@id, -1) <> -1

@ Радж: "ЕСЛИ ISNull(@id, -1) <> -1"

Я бы не стал это делать, так как он фактически заменяет запись в таблице.

Другие вопросы по тегам