1
37
首先,你应该 从未 在这样的客户端应用程序上执行SQL命令组合, 那是 什么是SQL注入。(对于没有自己特权的管理工具来说是可以的,但对于共享使用应用程序则不是这样)。 其次,是的,对存储过程的参数化调用既干净又安全。 然而 ,因为您需要使用动态SQL来执行此操作,所以仍然不希望在执行的查询的文本中包含传递的字符串。相反,您希望使用传递的字符串查找 实际的 允许用户以这种方式查询的表。 下面是一个简单天真的例子:
有些人已经公平地问了为什么这样更安全。希望Bobby的小桌子能更清楚地说明这一点:
更多问题的答案:
|
2
5
(un)幸运的是,没有办法做到这一点——除了用于动态SQL生成之外,不能将表名作为参数传递给存储代码。在决定在哪里生成SQL代码时,我更喜欢应用程序代码,而不是存储的代码。应用程序代码通常更快、更容易维护。 如果您不喜欢正在使用的解决方案,我建议您进行更深入的重新设计(即更改架构/应用程序逻辑,这样您就不必在任何地方将表名作为参数传递)。 |
3
2
我反对在存储过程中动态生成SQL;这会给您带来麻烦,并可能导致注入漏洞。 相反,我将分析可能受查询影响的所有表,并创建某种枚举,以确定用于查询的表。 |
4
2
听起来你最好使用ORM解决方案。 当我在存储过程中看到动态SQL时,我会感到害怕。 |
5
1
您可以考虑的一件事是生成一个包含您想要的相同SQL命令的case语句,对每个有效表执行一次,然后将表名作为字符串传递到此过程中,并让case选择要运行的命令。 顺便说一下,作为一个安全人员,上面的建议告诉您从系统表中进行选择,以确保您有一个有效的表,这对我来说似乎是一个浪费的操作。如果有人可以注入传递了QuoteName(),那么注入将在系统表和底层表上工作。唯一有助于确保它是一个有效的表名的方法,我认为上面的建议是更好的方法,因为您根本不使用QuoteName()。 |
6
0
根据这些表中的列集是相同的还是不同的,从长远来看,我将以两种方式处理它: 1)如果它们相同,为什么不创建一个将用作选择器的新列,该列的值是从用户提供的参数派生的?(这是性能优化吗?) 2)如果它们不同,处理它们的机会也不同。因此,似乎将select/handle代码拆分为单独的块,然后分别调用它们是我最模块化的方法。您将重复“select*from”部分, 但在这种情况下,表集可能是有限的。 允许调用代码提供表名的两个任意部分来进行选择,感觉非常危险。 |
7
0
我不知道为什么数据分散在几个表上,但听起来你破坏了其中一个基本原理。数据应该在表中,而不是作为表名。 如果表的布局或多或少相同,请考虑是否最好将数据放在单个表中。这将解决动态查询的问题,并使数据库布局更加灵活。 |
8
0
您可以选择该过程,而不是根据用户输入值查询表。
这就是说
因为您有大约50个表,所以这可能不是一个可行的解决方案,因为这需要您做很多工作。 |
9
0
实际上,我想知道如何传递表名以在存储过程中创建表。通过阅读一些答案并尝试在末尾进行一些修改,我最终能够创建一个以名称作为参数传递的表。下面是供其他人检查其中任何错误的存储过程。 使用[数据库名称] 去 /******对象:storedprocedure[dbo]。[sp eu createddynamicable]脚本日期:2015年6月20日16:56:25******/ 将Ansi_Nulls设置为打开 去 打开带引号的标识符 去 创建过程[dbo]。[sp_createddynamicable] @名称varchar(255) AS 开始 设置NoCon; 声明@sql nvarchar(max)
结束 |
10
0
@ RBarry Young 您不需要将方括号添加到查询字符串中的@actualtablename,因为它已经包含在信息“schema.tables”中查询的结果中。否则,执行时将出现错误。 将proc spcountanytablerows(@passedtablename as nvarchar(255))创建为 --统计任何非系统表中的行数, 安全地 开始 将@actualtablename声明为nvarchar(255)
结束 |