我有一个存储过程定义如下。
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
我使用了Execute 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?
答案 0 :(得分:1)
动态sql解决方案很乱,难以维护。 IMO最好将列表解析为临时表或变量并加入它。
答案 1 :(得分:0)
您有两种选择。将整个SQL创建为nvarchar并使用EXEC(statement)
或将分隔的输入字符串解析为临时表,然后使用WHERE SalesDate in(SELECT value FROM #t)
E.g。
EXEC(N'SELECT sum(Amount) FROM Sales WHERE SalesDate in ('+ @DateFilter + N') group by SalesDate')
这种方法可以为SQL注入攻击提供漏洞。
答案 2 :(得分:0)
CREATE PROCEDURE GetSales
@dateFilter nvarchar(50)
AS
BEGIN
execute('SELECT sum(Amount) FROM Sales WHERE SalesDate in (' + @dateFilter + ') group by SalesDate');
END
答案 3 :(得分:0)
我从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 开始 DECLARE @pos int, @nextpos int, @valuelen int
SELECT @pos = 0,@ nextpos = 1
WHILE @nepospos> 0 开始 SELECT @nepospos = charindex(',',@ list,@ apos + 1) SELECT @valuelen = CASE WHEN @nepospos> 0 然后@nextpos ELSE len(@list)+ 1 结束 - @pos - 1 INSERT @tbl(PeriodFilter) VALUES(substring(@list,@ apos + 1,@ valuelen)) SELECT @pos = @nextpos 结束 返回 END
这个过程 ALTER PROCEDURE [dbo]。[GetSales](@ dateFilter nvarchar(50)) 如 开始 - 添加SET NOCOUNT ON以防止出现额外的结果集 - 干扰SELECT语句。 设置NOCOUNT ON; SELECT sum(金额) 来自销售 在哪里SalesDate(select * from dbo.iter $ simple_intlist_to_tbl(@dateFilter)) 按SalesDate分组
END
cal
DECLARE @return_value int
EXEC @return_value = [dbo]。[GetSales] @dateFilter = N'May-2010,Apr-2010'
选择'返回值'= @return_value
GO