0

我的任务是构建一个查询(只是 where 子句)并将其存储在数据库中。然后它将由存储过程执行。

我想使用参数化动态查询,但是将查询与数据库中的参数分开存储、在 SQL 中读取并将参数与 where 子句联系起来很尴尬。尴尬在于参数的数量和类型是任意的。

我不想要未参数化的动态 SQL,因为搜索值是由用户提供的,而且我没有找到防止 SQL 注入的可靠方法。

有没有一种优雅的方法?

我正在使用 .NET 和 SQL Server。


我正在谈论的示例:

-- @filterId is passed to the SP

declare @sql nvarchar(max)
set @sql = 'select id, name, otherField from Items where' + whereClause 
           from Filters 
           where id = @filterId

create table #items {
  id int not null,
  name nvarchar(100),
  otherField nvarchar(200)
}

insert into #items exec(@sql)

-- do something with items and return result

编辑:有人建议我避免使用主观术语以获得有意义的回应。我相信定义什么是“最佳”和“优雅”会做。因此,当我说“最佳”时,我正在寻找一种比其他解决方案更安全、快速、可读和可维护的解决方案。“优雅” - 用最少的代码完成任务,没有太多假设,例如,如果我需要处理任意参数集,我不想为可能的参数创建 20 个占位符或为所有可能的列创建一个表参数类型并通过合并获得正确的值。

4

2 回答 2

0

我会说你做错的一件事是

exec(@sql)

指令本身没有任何问题,但是您很容易受到 SQL 注入的攻击。有人可以很容易地输入'select * from thing DROP TABLE Orders'。如果那个人有权利,他们就会放弃你的桌子。更好的方法是

exec sp_executesql @sql

确保 @sql 是 unicode varchar,您在示例中已经这样做了。sp_executesql 还采用更灵活的选项参数参数。

另外请记住,如果您说“我正在使用 .NET”Linq 有一些非常酷的事情,它可以使用实体框架通过模型层将 SQL 从数据库中抽象出来,您还可以执行动态 Linq。这提供了一个抽象层来处理 SQL 之上的工作,这在您可以使用 .NET 枚举和列表对数据进行建模以及在整个过程中从不直接连接到数据库的层运行其他代码的方式上更可取。

于 2013-04-09T23:19:23.903 回答
0

是的,我们可以在动态查询中使用执行@sql。当您使用动态查询进行动态搜索时,构建一个不允许单引号 ' 的正则表达式模式以防止 sql 注入。

于 2020-05-05T20:49:39.250 回答