Перейти к содержанию

Использование отрицания Не для условия И в секции ГДЕ запроса

Использование НЕ перед логической конструкцией И фактически означает выражение с условием ИЛИ. Не рекомендуется использовать логическое ИЛИ в условиях запроса в секции ГДЕ.

Подобные сложные условия могут привести к выбору неоптимального плана и медленной работе запроса.

Простого универсального способа переписать такой запрос без использования ИЛИ не существует. Следует проанализировать решаемую задачу и попытаться найти другой алгоритм ее решения.

Цитата из стандарта ИТС:

2.1. В основном условии оператор ИЛИ можно использовать только для последнего из используемых или единственного поля индекса, когда оператор ИЛИ можно заменить на оператор В.

ПРАВИЛЬНО:

ГДЕ
    Таблица.Поле = &Значение1
    ИЛИ Таблица.Поле = &Значение2

т.к. можно переписать при помощи оператора В (специально переписывать не нужно, можно оставить, как есть):

ГДЕ
    Таблица.Поле В (&Значения)

НЕПРАВИЛЬНО:

ГДЕ
    Таблица.Поле1 = &Значение1
    ИЛИ Таблица.Поле2 = &Значение2

нельзя переписать при помощи "В", но можно переписать при помощи "ОБЪЕДИНИТЬ ВСЕ" (каждое поле Поле1 и Поле2 должны быть проиндексированы):

ГДЕ
    Таблица.Поле1 = &Значение1

ОБЪЕДИНИТЬ ВСЕ

ГДЕ
    Таблица.Поле2 = &Значение1

Примечание: заменить ИЛИ на ОБЪЕДИНИТЬ ВСЕ можно не всегда, убедитесь, что результат будет действительно тем же, что и при ИЛИ, перед тем, как применять.

2.2. В дополнительном условии оператор ИЛИ можно использовать без ограничений.

ПРАВИЛЬНО 1:

ГДЕ
    Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
    И // Дополнительное условие (можно использовать ИЛИ)
    (Таблица.Поле2 = &Значение2 ИЛИ Таблица.Поле3 = &Значение3)

ПРАВИЛЬНО 2:

ГДЕ
    (Таблица.Поле1 = &Значение1 ИЛИ Таблица.Поле1 = &Значение2)
    И
    (Таблица.Поле2 = &Значение3 ИЛИ Таблица.Поле2 = &Значение4)

т.к. можно переписать при помощи В (специально переписывать не нужно, можно оставить, как есть):

ГДЕ
    Таблица.Поле1 В (&Значения1)   // Основное условие
    И Таблица.Поле2 В (&Значения2) // Дополнительное условие (или наоборот)

См. также

Экранирование кода

// sonar:UsingNoWithLogicalAndInWhere:off
// sonar:UsingNoWithLogicalAndInWhere:on