Использование обнуляемых столбцов в предложении 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"
Я бы не стал это делать, так как он фактически заменяет запись в таблице.