3

我有一个 ASP.NET MVC 3 应用程序,它允许用户创建自己的过滤器。之类amount > 5 and amount <= 7的,等等。用户可以选择金额值和运算符。

我的问题是如何将这些过滤器传递给检索数据的存储过程。存储过程已经非常复杂,这意味着传递了很多参数,这些参数被检查为空,所以我不能真正应用我在这里找到的答案:T-SQL 存储过程 - 动态 AND/OR 运算符

我还有其他方法可以做到这一点吗?

4

2 回答 2

4

运算符不能参数化。由于您提到这是一个存储过程,唯一的选择是在SP内部编写T-SQL,并使用sp_executesql,即

//TODO : verify (whitelist) that @operator is in a known set of values...
// '=', '<>', '>', '<' etc - otherwise security risk
declare @sql varchar(4000) = 'select * from Foo where Bar '
          + @operator + ' @value'
exec sp_executesql @sql, N'@value int', @value

这会即时构建查询 ( @sql),但始终保持值 ( @value) 参数化,因此我们只需将运算符 ( @operator) 列入白名单。

只是为了显示值如何保持参数化,我们也可以使用:

//TODO : verify (whitelist) that @operator is in a known set of values...
// '=', '<>', '>', '<' etc - otherwise security risk
declare @sql varchar(4000) = 'select * from Foo where Bar '
          + @operator + ' @p'
exec sp_executesql @sql, N'@p int', @value

这里,@p内部sql@value中的参数名称,是存储过程中的参数名称;第三/第四/第五/等参数sp_executesql映射到第二个参数中声明的参数 to sp_executesql(在本例中,声明为@p)。

请注意,如果这不是存储过程,您可以在 C# 中执行查询构造步骤,再次将值保留为参数。

于 2012-10-02T13:43:13.900 回答
1

我认为唯一的方法是使用动态 sql,例如sq_executesql。这允许您将 SQL 语句创建为字符串,然后执行它。但这可能意味着对现有存储过程的大量重写!

于 2012-10-02T13:44:21.670 回答