Фильтр критериев Sql в виде запятой - PullRequest
2 голосов
/ 21 октября 2010

У меня есть сохраненный процесс, который определяется следующим образом.

PROCEDURE [dbo].[GetSales](@dateFilter nvarchar(50))
AS
BEGIN
     SELECT sum(Amount)
     FROM Sales
     WHERE SalesDate in (' + @dateFilter  + ')
     group by SalesDate 

END

для выбора данных из этой таблицы

Id SalesDate     Amount
1   Apr-2010       40.25
2   May-2010       12.10
3   Jun-2010        2.50

Я использовал команду «Выполнить sp» и передал этот текст «Mar-2010», «Apr-2010»

Звонок сгенерировал этот код и ничего не восстановил.

DECLARE @return_value int

EXEC    @return_value = [dbo].[GetSales]
    @dateFilter = N'''Mar-2010'',''Apr-2010'''

SELECT  'Return Value' = @return_value

Но это (оператор вызова X) работает

 SELECT sum(Amount)
     FROM Sales
     WHERE SalesDate in ('Mar-2010','Apr-2010')
     group by SalesDate 

возвращение

(No column name)
40.25

Как я могу изменить фильтр параметров, чтобы сохраненный процесс использовал его как оператор X выше?

Ответы [ 4 ]

1 голос
/ 21 октября 2010

Динамическое решение SQL является грязным и сложным в обслуживании.IMO, лучше разобрать список во временную таблицу или переменную и объединить ее.

Создание таблицы SQL из объединенного списка с запятыми

0 голосов
/ 21 октября 2010

Я нашел ответ от http://www.sommarskog.se/arrays-in-sql-2005.html

ALTER FUNCTION [dbo]. [Iter $ simple_intlist_to_tbl] (@ list nvarchar (MAX)) ВОЗВРАЩАЕТСЯ @Tbl TABLE (PeriodFilter nvarchar (10)) AS НАЧАТЬ ОБЪЯВИТЬ @pos int, @nextpos int, @valuelen int

SELECT @pos = 0, @nextpos = 1

WHILE @nextpos> 0 НАЧАТЬ SELECT @nextpos = charindex (',', @list, @pos + 1) SELECT @valuelen = CASE WHEN @nextpos> 0 THEN @nextpos ELSE len (@list) + 1 КОНЕЦ - @pos - 1 INSERT @tbl (PeriodFilter) VALUES (подстрока (@list, @pos + 1, @valuelen)) SELECT @pos = @nextpos КОНЕЦ ВЕРНУТЬ END

этот процесс ALTER PROCEDURE [dbo]. [GetSales] (@ dateFilter nvarchar (50)) КАК НАЧАТЬ - SET NOCOUNT ON добавлен для предотвращения дополнительных наборов результатов - вмешательство в операторы SELECT. УСТАНАВЛИВАЙТЕ NOCOUNT ON; ВЫБЕРИТЕ сумму (Сумма) ОТ продаж ГДЕ SalesDate in (выберите * из dbo.iter $ simple_intlist_to_tbl (@dateFilter)) сгруппировать по SalesDate

END

Cal

ОБЪЯВИТЬ @return_value int

EXEC @return_value = [dbo]. [GetSales] @dateFilter = N'May-2010, апрель-2010 '

ВЫБРАТЬ «Возвращаемое значение» = @ return_value

GO

0 голосов
/ 21 октября 2010
CREATE PROCEDURE GetSales
    @dateFilter nvarchar(50)
AS
BEGIN
   execute('SELECT sum(Amount) FROM Sales WHERE SalesDate in (' + @dateFilter + ') group by SalesDate');
END
0 голосов
/ 21 октября 2010

У вас есть два варианта.Либо создайте весь SQL как nvarchar и используйте EXEC(statement), либо проанализируйте входную строку с разделителями во временной таблице, а затем используйте WHERE SalesDate in(SELECT value FROM #t)

Например,

EXEC(N'SELECT sum(Amount) FROM Sales WHERE SalesDate in ('+ @DateFilter + N') group by SalesDate')

Этот подход может создать лазейку для атак SQL-инъекций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...