2015-01-23 6 views
-3

У меня есть форма C# для поиска в таблице с различными параметрами, которые пользователь может фильтровать процедуру поиска.Необязательные параметры в where where

У меня есть 4 текстовых поля, например txt1, txt2, txt3 и txt4.

Пользователь может заполнить каждое текстовое поле для поиска, например, txt1 или txt1 и txt2 или txt1 и txt и txt4, либо оставить их пустыми и использовать всю комбинацию этих текстовых полей. Итак, как я могу написать одну процедуру выбора, чтобы охватить все эти параметры.

Я написал эту процедуру, но это не поможет:

CREATE proc sp_searchZ 
@minprice bigint=null,@maxprice bigint=null,@minarea int=null,@maxarea int=null,@location nvarchar(50)=null,@kind nvarchar(50)=null 
as 

SELECT * 
    FROM Landtbl 
WHERE ((@minprice is null and @maxpriceis null) or ([Price] between @minprice and @maxprice)) 
and 
     ((@minarea is null and @maxarea is null) or ([area] between @minarea and @maxarea)) 

and ((@location is null)or([location][email protected])) 
and ((@kind is null) or ([kind][email protected])) 
+1

Что значит «это не поможет»? Я думаю, что ваша основная логика звучит, вы получаете нулевые записи, когда ожидаете чего-то? –

+0

'@maxpriceis null' - это опечатка в вашей процедуре магазина или только в этом вопросе? –

+0

Извините, я понял ... но забыл свой код ... что я могу сделать, когда пользователь динамически фильтрует и заполняет некоторые текстовые поля? –

ответ

0

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

DECLARE @sqlString nvarchar(max); 
DECLARE @sqlWhere nvarchar(max); 
DECLARE @sqlParams nvarchar(max); 

SET @sqlString = 'SELECT * FROM Landtbl ' 
SET @sqlWhere = 'WHERE 1=1 ' 

IF (@minprice IS NOT NULL and @maxprice IS NOT NULL) 
BEGIN 
    SET @sqlWhere = @sqlWhere + 'AND [Price] BETWEEN @minprice AND @maxprice ' 
END; 

IF (@location IS NOT NULL) 
BEGIN 
    SET @sqlWhere = @sqlWhere + 'AND [location][email protected] ' 
END; 
-- any other conditional logic 

SET @sqlParams = N'@minprice bigint,@maxprice bigint,@minarea int,@maxarea int,@location nvarchar(50),@kind nvarchar(50)'; 

SET @sqlString = @sqlString + @sqlWhere; 

EXEC sp_executesql @sqlString, @sqlParams, @minprice ,@maxprice ,@minarea,@maxarea,@location,@kind 

Это должно работать хорошо, и может быть использован, чтобы сделать некоторые действительно сложные вещи. Я надеюсь, что это помогает

+0

tnx, но я не знаю, что означает EXEC sp_executesql.я должен написать его конец процедуры, что именно делает этот код? –

+0

EXEC sp_executesql будет запускать команду, которую вы создаете динамически. Он построен в SQL, поэтому вам не нужно ничего делать. Вы все равно можете вызвать свою хранимую процедуру как обычно. Вы уже пробовали? Поместите весь мой код в определение storedProc, объявите соответствующие параметры и запустите его. – Chris

+0

Могу ли я удалить эту последнюю строку из моей процедуры? Если да. Как изменить эту процедуру? –

0

Там нет необходимости для динамического SQL здесь, я делаю такие вещи все время, как это (помните, я сказал, ваша логика звук?):

SELECT * FROM table WHERE ((@optionalparam IS NULL) OR ([field][email protected])) 

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

EDIT:

Попробуйте это, откройте SSMS и откройте новое окно запроса и введите следующие данные:

DECLARE @minprice INT /* or whatever datatype you are using */ 
DELCARE @maxprice INT 
SELECT @minprice=1, @maxprice=9999 

SELECT 
    * 
FROM 
    Landtbl 
WHERE 
    ((@minprice IS NULL and @maxprice IS NULL) OR ([Price] BETWEEN @minprice AND @maxprice)) 

, если это работает, то добавьте следующий бит

SELECT 
    * 
FROM 
    Landtbl 
WHERE 
    ((@minprice IS NULL and @maxprice IS NULL) OR ([Price] BETWEEN @minprice AND @maxprice)) 
AND ((@minarea is null and @maxarea is null) or ([area] between @minarea and @maxarea)) 

, если работы добавляют следующий бит и так далее, пока не сработает. Бит, который вы добавили последним, - это бит, который не работает.

+0

На самом деле динамический sql является разумным подходом здесь, но не требуется с sql 2008. Это был единственный способ сделать это несколько лет назад и сохранить производительность приемлемой. Образец, который вы используете, также является моим предпочтительным подходом, но вам нужно убедиться, что вы добавили OPTION RECOMPILE, чтобы не получить устаревшие планы выполнения, которые неэффективны с разными параметрами. –

+0

@Sean, да, полностью согласен со всем, что вы говорите, но я не хотел усложнять в этот момент, поскольку OP, похоже, немного затрудняет получение фактического запроса. –

+0

Я не могу получить его. Вы можете объяснить больше plz –

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