Условная строка SQL сравнивается в предложении Where - PullRequest
3 голосов
/ 26 января 2012

Используя SQL Server, у меня есть хранимая процедура, которую я хочу сделать необязательным для поиска строк.

@search - это параметр.Если @search имеет значение, я хочу найти строку, в противном случае, если оно пустое, оно должно обойти поиск.

Я просто хотел узнать ваши мысли об оптимальном способе написания необязательного поиска строки вГДЕ.

Прямо сейчас у меня это как

AND (@search = '' OR [t4].number like '%'+@search+'%')

Но я не смог выяснить, оценивает ли подобное, даже если @search = '' истинно

Если он по-прежнему сравнивает обе стороны ИЛИ, то я подумал об использовании этого

AND (CASE WHEN @search = '' THEN 1 
          ELSE (CASE WHEN [t4].number like '%'+@search+'%' THEN 1 
                     ELSE 0 END) END) = 1

Редактировать: я провел пару тестов, и похоже, что случай меньше читает.

Ответы [ 4 ]

2 голосов
/ 26 января 2012

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

Однако сравнение поля varchar с '%%' с LIKE все равно будет соответствовать.

2 голосов
/ 26 января 2012

Я не уверен, как это будет работать с LIKE, но мой любимый способ выразить это:

select * from 
  mytable
 where myfield = COALESCE(@optionalValue, myfield)

И если @optionalValue равно нулю, то это оценивается как myfield = myfield, в противном случае myfield проверяется на @optionalValue.

Редактировать: Как оказалось, вы можете сказать:

select * from 
  mytable
 where myfield like ('%' + COALESCE(@optionalValue, myfield) + '%' )

И, кажется, работает нормально.

1 голос
/ 26 января 2012

Вы (в основном) можете предположить, что оценка короткого замыкания выполняется в выражении CASE, но не в выражениях вашего первого типа.

В этой статье показан хотя бы один крайний случай, когда даже CASE короткое замыкание не срабатывает.

1 голос
/ 26 января 2012

Но я не смог выяснить, проверяет ли подобное, даже если @search = '' верно

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

  create table #temp
    (
        dat smalldatetime,
        Solution_ID int,
        stri varchar(100)
    )

insert into #temp(dat, Solution_ID, stri)values(GETDATE(), 1,  '')
insert into #temp(dat, Solution_ID, stri)values(GETDATE()+1, 2,  'ed')
insert into #temp(dat, Solution_ID, stri)values(GETDATE()+2, 3, 'edede')

select * from #temp
where myfield like '%' + coalesce(@searchString, myfield) + '%'
drop table #temp

enter image description here

Вы можете рассмотреть возможность добавления некластеризованного индекса в столбец, который не будет сканировать всю таблицу, поскольку у него есть преимущество индекса в нижней части страницы, содержащей адрес всех записей Non ClusteredIndex => Refernce

...