ИЛИ Короткое замыкание оператора в SQL Server

Я хочу проконсультироваться с SQL Server ИЛИ короткого замыкания

Код:

   DECLARE @tempTable table
      (
         id int
      )
      INSERT @tempTable(id) values(1)

      DECLARE @id varchar(10)
      SET @id = 'x'
      SELECT * FROM @tempTable WHERE 1=1 OR id = @id --successfully
      SELECT * FROM @tempTable WHERE @id = 'x' OR id = @id --Exception not Convert 'x' to int

Почему? 1=1 и @id='x' верно.

Оператор SQL Server ИЛИ: функция короткого замыкания?

СПАСИБО


person NotTwoWayStreet    schedule 27.06.2012    source источник
comment
Нет никаких гарантий относительно того, как и какие части условия OR оцениваются в первую очередь (или вообще оцениваются). В этом отношении T-SQL НЕ похож на C#. Вы нельзя полагаться на булево короткое замыкание.   -  person marc_s    schedule 27.06.2012
comment
Why? 1=1 and @id='x' is true - это или на самом деле, а не и.   -  person juergen d    schedule 27.06.2012
comment
Здесь, в этом INSERT @tempTable(id) values(1), INTO отсутствует.   -  person vijay    schedule 27.06.2012
comment
ИЛИ короткое замыкание Мои сомнения, но моя офисная кодировка sql есть ((@id is NULL OR id = id) AND (@name IS NULL OR name=@name)) поэтому я хотел бы знать, является ли короткое замыкание, потому что это решение эффективность процесса Для этого просто повторно используйте план запроса   -  person NotTwoWayStreet    schedule 27.06.2012


Ответы (3)


В SQL не требуется, чтобы предложение ИЛИ прерывалось раньше. Другими словами, от оптимизатора зависит, проверять ли оба условия одновременно. Я не эксперт по оптимизатору MSSQL, но я видел случаи, когда оптимизатор имел и не замыкал предложение OR.

person Steven Mastandrea    schedule 27.06.2012
comment
ИЛИ короткое замыкание Мои сомнения, но моя офисная кодировка sql есть ((@id is NULL OR id = id) AND (@name IS NULL OR name=@name)) поэтому я хотел бы знать, является ли короткое замыкание, потому что это решение эффективность процесса Для этого просто повторно используйте план запроса - person NotTwoWayStreet; 27.06.2012

Только что наткнулся на этот вопрос и уже нашел эту запись в блоге: http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/

SQL-сервер может оптимизировать запрос в любом месте, где он считает нужным, поэтому в примере, приведенном в сообщении блога, вы не можете полагаться на короткое замыкание.

Тем не менее, ДЕЛО, по-видимому, задокументировано для оценки в письменном порядке - проверьте комментарии к этому сообщению в блоге.

person stolsvik    schedule 14.08.2012

Очевидно, что сервер MS Sql поддерживает теорию короткого замыкания, чтобы повысить производительность, избегая ненужных проверок,

Поддерживающий пример:

SELECT 'TEST'
WHERE 1 = 'A'

SELECT 'TEST'
WHERE 1 = 1 OR 1 = 'A'

Здесь первый пример приведет к ошибке «Сбой преобразования при преобразовании значения varchar «A» в тип данных int».

В то время как второе выполняется легко, поскольку условие 1 = 1 оценивается как ИСТИНА, и, следовательно, второе условие вообще не выполняется.

Более того

SELECT 'TEST'
WHERE 1 = 0 OR 1 = 'A'

здесь первое условие будет оценено как ложное, и, следовательно, СУБД перейдет ко второму условию, и снова вы получите ошибку преобразования, как в приведенном выше примере.

ПРИМЕЧАНИЕ. Я НАПИСАЛ ОШИБОЧНОЕ УСЛОВИЕ ТОЛЬКО ДЛЯ ПОНИМАНИЯ, ЕСЛИ УСЛОВИЕ ВЫПОЛНЯЕТСЯ ИЛИ КОРОТКОЕ ЗАМЫКАНИЕ, ЕСЛИ ЗАПРОС РЕЗУЛЬТАТ В ОШИБКЕ ОЗНАЧАЕТ УСЛОВИЕ ВЫПОЛНЕННОЕ, КОРОТКОЕ ЗАМЫКАНИЕ В ПРОТИВНОМ СЛУЧАЕ.

ПРОСТОЕ ОБЪЯСНЕНИЕ

Рассмотреть возможность,

WHERE 1 = 1 OR 2 = 2

поскольку первое условие оценивается как TRUE, бессмысленно оценивать второе условие, потому что его оценка в любом значении вообще не повлияет на результат, поэтому для Sql Server это хорошая возможность сэкономить время выполнения запроса. пропуская ненужную проверку условий или оценку.

в случае "ИЛИ", если первое условие оценено как ИСТИНА, вся цепочка, связанная "ИЛИ", будет считаться оцененной как истинная без оценки другие.

condition1 OR condition2 OR ..... OR conditionN

если условие1 оценивается как истинное, оставит все условия до тех пор, пока условиеN не будет пропущено. В обобщенных словах при определении первого ИСТИНА все остальные условия, связанные оператором ИЛИ, будут пропущены.

Рассмотрим второе условие

WHERE 1 = 0 AND 1 = 1

поскольку первое условие оценивается как FALSE, бессмысленно оценивать второе условие, потому что его оценка в любом значении вообще не повлияет на результат, поэтому снова это хорошая возможность для Sql Server сэкономить время выполнения запроса. пропуская ненужную проверку условий или оценку.

в случае "И", если первое условие оценено как ЛОЖЬ, вся цепочка, связанная с "И", будет считаться оцененной как ЛОЖЬ без оценивая других.

condition1 AND condition2 AND ..... conditionN

если условие1 оценивается как FALSE, остальные условия остаются до тех пор, пока conditionN не будет пропущено. В обобщенных словах при определении первого FALSE все остальные условия, связанные с помощью AND, будут пропущены.

ПОЭТОМУ, МУДРЫЙ ПРОГРАММИСТ ДОЛЖЕН ВСЕГДА ПРОГРАММИРОВАТЬ ЦЕПОЧКУ УСЛОВИЙ ТАКИМ ОБРАЗОМ, ЧТОБЫ ПЕРВЫМ ОЦЕНИВАЛОСЬ МЕНЕЕ ДОРОГОЕ ИЛИ НАИБОЛЕЕ ИСКЛЮЧАЮЩЕЕ УСЛОВИЕ, ИЛИ УСТРОЙСТВОВАТЬ УСЛОВИЯ ТАКИМ ОБРАЗОМ, ЧТО МОЖЕТ ИЗВЛЕЧЬ МАКСИМАЛЬНУЮ ПРЕИМУЩЕСТВУ ОТ КОРОТКОГО ЗАМЫКАНИЯ.

С уважением и благодарностью,

Rk_Hirpara

person RkHirpara    schedule 12.06.2015
comment
Причина понижения: всегда тестируйте вещи на реальном сервере с разумным набором данных. Например, попробуйте это более реалистичное предложение where для символьного поля — где isnumeric(fieldname) = 1 AND convert(decimal, fieldname) ‹= 0 — вы обнаружите, что оно вызывает ошибку преобразования в строках, где isnumeric = 0, даже если технически не нужно оценивать второе условие для таких строк. - person Jasmine; 03.11.2015
comment
Я почти никогда не голосую против, но этот ответ, по-видимому, просто неверен. - person Culme; 27.04.2018