Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
合并:SQL在SP中传递逗号分隔的值以进行筛选_Sql_Sql Server_Filtering_Csv - Fatal编程技术网

合并:SQL在SP中传递逗号分隔的值以进行筛选

合并:SQL在SP中传递逗号分隔的值以进行筛选,sql,sql-server,filtering,csv,Sql,Sql Server,Filtering,Csv,我在这里分享以下场景的综合分析: 我有一个“项目”表,我有一个搜索SP。我希望能够搜索多个项目代码,如: - Table structure : Item(Id INT, ItemCode nvarchar(20)) - Filter query format: SELECT * FROM Item WHERE ItemCode IN ('xx','yy','zz') 我希望使用存储过程动态地执行此操作。我将传递一个@ItemCodes参数,该参数将使用逗号(',')分隔值,搜索应如上所述执行

我在这里分享以下场景的综合分析:

我有一个“项目”表,我有一个搜索SP。我希望能够搜索多个项目代码,如:

- Table structure : Item(Id INT, ItemCode nvarchar(20))
- Filter query format: SELECT * FROM Item WHERE ItemCode IN ('xx','yy','zz')
我希望使用存储过程动态地执行此操作。我将传递一个@ItemCodes参数,该参数将使用逗号(',')分隔值,搜索应如上所述执行


嗯,我已经访问了很多帖子\论坛,下面是一些帖子:

    动态SQL可能是最不复杂的方式,但我不想考虑它,因为性能、安全性(SQL注入等)的参数…李>
还有其他方法,如XML等。。如果它们让事情变得复杂,我就不能使用它们

最后,请不要使用额外的临时表连接之类的性能攻击技巧。 我必须管理性能和复杂性

  • 我已经回顾了以上两篇文章,并讨论了提供的一些解决方案,这里有一些局限性:

这将要求我在将参数类型传递给SP时“声明”参数类型,这会扭曲抽象(我没有在任何参数中设置类型,因为它们都是以通用方式处理的)

这是一种结构化的方法,但它增加了复杂性,需要更改数据库结构级别,并且不像上面那样抽象

嗯,这似乎与我以前的解决方案相匹配。这是我过去所做的-

I created an SQL function : [GetTableFromValues] (returns a temp table populated each item (one per row) from the comma separated @ItemCodes)
下面是我如何在SP中的WHERE caluse过滤器中使用它-

SELECT * FROM Item WHERE ItemCode in (SELECT * FROM[dbo].[GetTableFromValues](@ItemCodes))
这一个是可重用的,看起来简单而简短(当然相对而言)。我错过的任何东西或任何有更好解决方案的专家(显然“在”上述各点的限制范围内)


谢谢。

我认为在这种情况下使用动态T-SQL将是实用的。如果您在设计时非常小心,那么动态sql的工作非常有魅力。我已经在无数的项目中利用了它,当它是合适的时候。话虽如此,让我来谈谈您的两个主要问题——性能和sql注入

关于性能,请阅读关于参数化动态SQL和sp_executesql(而不是sp_executesql)的T-SQL参考。参数化sql和使用sp_executesql的组合将确保查询计划被重用,并避免sp_重新编译,从而使您在性能上摆脱困境!我甚至在实时环境中也使用过动态sql,它在处理这两项时非常有用。为了让您满意,您可以在有或没有这两种优化的情况下对sp运行大约一百万次的循环调用,并使用sql profiler跟踪sp_重新编译事件

现在,关于SQL注入。如果您使用不正确的用户小部件(如文本框)来允许用户输入项目代码,这将是一个问题。在这种情况下,黑客可能会编写select语句并试图提取有关系统的信息。您可以编写代码来防止这种情况发生,但我认为这样做是一个陷阱。取而代之的是考虑使用一个合适的用户控件,如ListBox(取决于前端平台),允许多个选择。在这种情况下,用户只需从“显示的项目”列表中进行选择,您的代码将生成包含相应项目代码的字符串。基本上,您不会将用户文本传递给动态sql sp!您甚至可以使用更流畅的基于JQuery的选择小部件,但底线是,用户无法键入任何命中数据层的不可接受的文本

接下来,您只需要在数据库上使用一个简单的存储过程,该过程为itemcodes(例如“xyz”、“abc”)获取一个参数。在内部,它应该使用带有参数化动态查询的sp_executesql

我希望这有帮助。
-Tabrez

很多专家和论坛帖子都建议我直接在应用程序中使用动态T-SQL。。具有与部署SP相同的好处!!!这让我的问题变得自上而下,我可以通过一个完整的动态SQL生成,并在我的应用程序代码中真正“创造奇迹”。。这听起来公平吗?-------------------------------------我意识到您是从性能的角度来看这一点的,但在应用程序中保留动态查询构造的另一个很好的原因是,在SP中使用TSQL进行动态查询构造非常难看,而且很难维护。如果您真的想使用SP,我认为最好的方法是使用GetTableFromValues UDF,因为这确实避免了在SP中编写动态SQL。我同意如果使用时非常小心,T-SQL可以利用很多。然而,回到我的场景,T-SQL将始终面临SQL注入的威胁,应用程序开发人员必须确保他有一个安全的输入方法。我希望我的方法能让开发人员摆脱这种担忧,并为在筛选器中使用动态逗号分隔值提供一种干净、简单的方法。正如我所提到的,如果您控制前端输入的方式,使用sp路由可以避免sql注入。如果应用程序开发人员在另一个组中,并且您无法控制数据收集,那么最好对SQL关键字进行简单检查,例如SELECT、@symbol(系统变量)以及圆括号(用于筛选函数调用)。我认为,在大多数情况下,拥有一个参数化的存储过程可以避免这些问题,因为SQL参数是用引号编码的。但是,如果有疑问,可以将上述检查放在一个函数中,以便在启动sql之前测试字符串。最好使用该函数,因为它是全局的,并且在其他SP中也很有用。并将逻辑/控制/更改限制为单个功能。更好地进行进一步的增强。谢谢