3

С помощью SQL Server у меня есть хранимая процедура, в которой я хочу сделать строковый поиск необязательным.SQL Conditional String compare in Where where

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

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

Сейчас у меня есть как

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

Но то, что я не был в состоянии выяснить, является ли, как оценивает, даже если @search = '' верно

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

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

Edit: Я сделал пару тестов, и это выглядит так же менее читает.

+4

В общем, небезопасно использовать короткое замыкание (как в вашем первом выражении), так как оптимизатор можно оценить в любом порядке - см. [Http://rusanu.com/2009/09/13/on-sql- server-boolean-operator-short-circuit /] (http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/) – wmz

ответ

2

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

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

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

Edit:, как выясняется, вы можете сказать:

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

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

+0

Вы теряете какую-либо производительность, потому что вы сравниваете поле для себя? Разве это не заставило бы sql читать поля, даже если он его не использовал? – zeal

+0

Поле (err, данные столбца) для таблицы должно быть прочитано в любом случае. Поместите его в индекс и по крайней мере всю строку не нужно обрабатывать. –

1

Но то, что я не был в состоянии выяснить, является ли подобные им чеки, даже если @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

+0

Это хороший пример, но я не уверен, что вы пытаетесь сказать. Я хотел спросить, оценивает ли подобное, когда первое утверждение в OR истинно. – zeal

+0

PLease check the edit ... – Pankaj

2

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

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

+0

Я хотел, чтобы sql читал как можно меньше, чтобы повысить производительность, поэтому я думал, что он будет работать быстрее, если я смогу предотвратить чтение 'LIKE'. – zeal

+0

, вы можете рассмотреть возможность добавления некластеризованного индекса в столбец, который не будет сканировать полную таблицу из-за его индексного преимущества внизу страницы, который содержит адрес всех записей http://www.sql-server-performance.com/2004/индекс-структуры данных / – Pankaj

1

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

This article показывает вам, по крайней мере, один край, где даже CASE короткое замыкание не срабатывает.