2015-06-17 2 views
2

У меня больше элементов управления (предположим, что 10 элементов управления с текстовым полем, выпадающим списком, переключателями) в моем приложении форм Windows для фильтрации данных, которые все не являются обязательными, поэтому пользователь может фильтровать данные с помощью 1 или больше.Фильтрация нескольких столбцов в хранимой процедуре в SQL Server

Теперь я должен создать хранимую процедуру для фильтрации данных на основе их входов.

Ех: если пользователь вводит какой-либо текст в 1 текстовом поле управления, а оставшиеся 9 элементов управления с пустыми данными, я должен фильтровать данные только на том текстовом поле, которое вводил пользователь.

Если пользователь вводит какой-либо текст в 1 текстовом поле управления и 1 выпадающий список, а оставшиеся 8 элементов управления с пустыми данными, я должен фильтровать данные на основе только этого текстового поля и выпадающего списка, который был введен пользователем.

Что я должен делать?

В исходном коде:

Если пользователь ввел/выбранный текст на любом контроле, я передаю значение в качестве параметров еще я прохожу как «нуль», чтобы остальные все остальные параметры.

В хранимой процедуре:

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

if @Param1=null && @Param2=null && @Param3='SomeText' 
    begin 
     sELECT * FROM tABLE1 wHERE [email protected] 
    END 
if @Param1=null && @Param2='SomeText' && @Param3='SomeText' 
    begin 
     sELECT * FROM tABLE1 wHERE [email protected] AND [email protected] 
    END 

Примечание: мне нужно фильтровать данные с каждого столбца таблицы для каждого параметра, просто предположим @ Param1 - TableCOLUMN1, @ param2 - TableCOLUMN2, фильтр меняется в зависимости от параметров текста.

Если я сделаю это, моя хранимая процедура будет более огромной и очень большой, потому что у меня есть 10 параметров для проверки (только для вашей справки я дал 3 параметра выше образца).

Что я хочу:

Поскольку я дал 10 параметров, на основе параметров, имеющих значения (текст, кроме NULL) только я должен фильтровать данные, используя где условие.

Есть ли другой способ сделать это, или у кого-нибудь есть другие способы для этого?

+1

Прочитать [Условия динамического поиска в T-SQL] (http://www.sommarskog.se/dyn-search.html) –

ответ

1

Я хотел бы предложить что-то вроде этого:

SELECT * 
FROM TABLE1 
WHERE TableCOLUMN1=ISNULL(@Param1,TableCOLUMN1) 
AND TableCOLUMN2=ISNULL(@Param2,TableCOLUMN2) 
AND TableCOLUMN3=ISNULL(@Param3,TableCOLUMN3) 
AND TableCOLUMN4=ISNULL(@Param4,TableCOLUMN4) 
... and so on... 

Это будет фильтровать column1 по значению, если вы укажете param1 в противном случае он будет использовать сам columnvalue, который всегда будет истинным. Но это будет работать, только если ваши значения @Param были NULL в каждом случае, если вы их не будете использовать.

1

Пока вы сделаете свой Params по умолчанию нулевое значение и либо не передавать значение для Params вам не нужно или передать в DBNull значение, то вы можете выбирать, как этот

CREATE PROC dbo.SAMPLE 
(
    @Param1 VARCHAR(255) = NULL, 
    @Param2 VARCHAR(255) = NULL, 
    @Param3 VARCHAR(255) = NULL, 
    @Param4 VARCHAR(255) = NULL, 
    @Param5 VARCHAR(255) = NULL, 
    @Param6 VARCHAR(255) = NULL 
) 
AS 
BEGIN 
    SELECT * 
    FROM Table1 
    WHERE (@Param1 IS NULL OR TableCOLUMN1 = @Param1) 
      AND (@Param2 IS NULL OR TableCOLUMN2 = @Param2) 
      AND (@Param3 IS NULL OR TableCOLUMN3 = @Param3) 
      AND (@Param4 IS NULL OR TableCOLUMN4 = @Param4) 
      AND (@Param5 IS NULL OR TableCOLUMN5 = @Param5) 
    OPTION (RECOMPILE) -- as JamesZ suggested to prevent caching 
END 


EXEC dbo.SAMPLE @Param2 = 'SomeText' -- only filter where TableCOLUMN2 = @Param2 
+0

Полезно, потому что вы можете делать такие вещи, как '(@ Param1 = '' ИЛИ ​​TableCOLUMN1 in (@ Param1ToList)) ' – DavidC

1

Если таблица большой/вам нужно использовать индексы для извлечения строк, проблема с такой логикой заключается в том, что индексы не могут действительно использоваться.Там в основном два способа, как вы можете сделать это:

  1. Добавить option (recompile) к концу выберите заявление @Ionic или @ user1221684. Это приведет к перекомпиляции оператора каждый раз, когда выполняется, что может вызвать много накладных расходов на ЦП, если это вызвано часто.

  2. Создание динамических SQL и вызвать его с помощью sp_executesql

Пример:

set @sql = 'SELECT * FROM TABLE1 WHERE ' 

if (@Param1 is not NULL) set @sql = @sql + '[email protected] AND ' 
if (@Param2 is not NULL) set @sql = @sql + '[email protected] AND ' 
if (@Param3 is not NULL) set @sql = @sql + '[email protected] AND ' 

-- Note: You're not concatenating the value of the parameter, just it's name 

set @sql = @sql + ' 1=1' -- This handles the last 'and' 

EXEC sp_executesql @sql, 
    N'@Param1 varchar(10), @Param2 varchar(10), @Param3 varchar(10)', 
    @Param1, @Param2, @Param3 

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

+0

любое преимущество добавления 1 = 1 в конец инструкции, а не в начале и просто используя' 'AND TableCOLUMN1 = @ Param1 ''? – JamieD77

+0

Это не имеет значения. Это как раз то, как я это делаю, почему-то ...: D –

+0

На большой таблице накладные расходы процессора не будут слишком сложными - обычно. Вы получите больше производительности при перекомпиляции на большом столе, тогда вы потеряете, если ваш план будет плохим. :-) – Ionic

Смежные вопросы