2008-12-02 3 views
5

Я пытаюсь написать запрос для страницы расширенного поиска в моей системе архивации документов. Я пытаюсь выполнить поиск по нескольким необязательным параметрам. У меня есть около 5 параметров, которые могут быть пустыми строками или строками поиска. Я знаю, что мне не нужно было проверять каждую строку или пустое место и создавать отдельную хранимую процедуру для каждой комбинации.sql search query для нескольких необязательных параметров

Edit: Законченное с помощью:

ISNULL(COALESCE(@var, a.col), '') = ISNULL(a.col, '') 
+0

См. Также: http://stackoverflow.com/questions/532468/ignoring-a-null-parameter-in-t-sql/532510#532510 – 2009-02-12 15:07:14

ответ

8

Вы можете использовать COALESCE (или ISNULL) как так:

WHERE COALESCE(@var1, col1) = col1 
AND COALESCE(@var2, col2) = col2 
AND COALESCE(@var3, col3) = col3 
1

Вы можете поместить или находится в вашем ИНЕКЕ следующим образом:

WHERE 
    (@var1 = '' OR col1 = @var1) AND 
    (@var2 = '' OR col1 = @var2) AND 
    (@var3 = '' OR col1 = @var3) ... 
+0

Хотя это решение будет работать, оно невероятно дорого. Не используйте OR ... вместо этого используйте ISNULL (пример выше). – 2008-12-02 13:56:59

+2

Это решение будет работать во всех случаях. Решение IsNull/Coalesce будет работать только в контролируемых условиях. Когда вы используете Coalesce, вы все еще проверяете значение столбца равным EQUAL. Если значение в столбце равно NULL, оно не будет равно EQUAL, и строка НЕ ​​будет возвращена. – 2008-12-02 21:04:47

0

Вы можете передать дополнительные параметры хранимой процедуры, но оптимизатор будет строить план, основанный на конкретных вызовах, которые вы делаете для этого процесса. Есть несколько трюков в SQL Server 2005 и позже, чтобы избежать этого (параметр sniffing, «без компиляции» и т. Д.)

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

0

Еще лучше сделать необязательный параметр NULL, а затем проверить в ИНЕКЕ так же, как пустая строка случае ...

6

Я обычно делаю это: P

WHERE (@var1 IS NULL OR col1 = @var1) 
AND (@var2 IS NULL OR col2 = @var2) 

...

1

альтернативой является динамичным он создал SQL в Хранимой процедуре, это дает наилучший возможный план для запроса, и план будет создан и использован в любом случае (в 2005 году и выше).