4

基本上我必须从 SQL 数据库中构建项目列表,但是用户可以选择对 7 个过滤器的任意组合进行过滤,也可以选择要排序的列以及按方向排序。

正如您可以想象的那样,这会以大量不同的组合进行编码,并且数据集非常大,所以我想避免在应用程序中这样做。

到目前为止,在我的存储过程中,我尝试过:

  • 构建一个查询字符串,虽然这非常简单且易于遵循,但它会使应用程序对 SQL 注入开放,所以我宁愿避免这种情况。

  • 使用一组IF ELSE语句来运行适当的参数化 SQL,但这很快就会变成一棵巨大的树,维护起来将是一场噩梦。

我不是第一个需要这样的解决方案的人,一定有比上述更好的方法吗?IF另外作为一个附带问题,除了做很多s之外,是否有一种以参数化方式进行排序和按方向排序的好方法?

4

2 回答 2

2

构建一个查询字符串,虽然这非常简单且易于遵循,但它会使应用程序对 SQL 注入开放,所以我宁愿避免这种情况。

如果您使用sp_executesql并将参数作为参数传递给该存储过程,则不会。由于您将数据作为参数提供,因此不会有 sql 注入

http://sqlinthewild.co.za/index.php/2009/04/03/dynamic-sql-and-sql-injection/

http://blogs.msdn.com/b/raulga/archive/2007/01/04/dynamic-sql-sql-injection.aspx

我也尝试过使用一组 IF ELSE 语句来运行正确的参数化 SQL,但这很快就会变成一棵巨大的树,维护起来将是一场噩梦。

如果您使用 IF ELSE 则同意,但还有一种称为捕获所有查询的模式

WHERE (ProductID = @Product Or @Product IS NULL)
AND (ReferenceOrderID = @OrderID OR @OrderID Is NULL)
...

更多信息在这里 http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/

请务必在末尾指定 OPTION (RECOMPILE),否则您的查询可能会因所谓的参数嗅探而受到影响

Also as a side question is there a good way to do order by and order by direction in a parameterised way, besides doing lots of IFs?

SQL 存储过程中的动态排序可能重复

最后,您可以使用 sp_executesql 或捕获所有查询(这是这两种尝试过的解决方案的常见问题)。我通常更喜欢捕获所有查询,但不要忘记指定选项(重新编译)。

于 2012-06-13T11:41:21.193 回答
2

对于过滤,使用COELSCE来按任何条件组合进行过滤。在您的存储过程中,将有一个用户将搜索的所有参数的列表,然后在您的查询中将类似于:

 SELECT * 
 FROM YourTable t
 WHERE 1 = 1
 AND t.FirstColumn = COALESCE(@FirstColumnParam, t.FirstColumn)
 AND t.SecodndColumn = COALESCE(@SecondColumnParam, t.SecondColumn) 
 ....

如果任何参数为空,则跳过该条件。1=1如果没有过滤器代码传递给您的查询。

对于排序:您可以使用该CASE语句按任何选择的列排序:

ORDER BY ( CASE WHEN @OrderByParam = 1 Then FirstColumn ELSE .... END)
于 2012-06-13T11:42:00.570 回答