【问题标题】:Dynamic SQL vs Parameterised query动态 SQL 与参数化查询
【发布时间】:2012-01-07 01:12:35
【问题描述】:

这个存储过程被认为是动态 SQL 还是参数化查询?

CREATE PROCEDURE [dbo].[my_dodgy_sp]
    @varchar1 varchar(50),
    @varchar2 varchar(50)
AS
BEGIN
    ...

    EXEC [dbo].[my_really_special_sp] @varchar1 @varchar2;
END

如果你能告诉我这是否是动态/参数化的,那么额外的带有樱桃的巧克力甜甜圈:

CREATE PROCEDURE [dbo].[my_super_dodgy_sp]
    @varchar1 varchar(50),
    @varchar2 varchar(50),
    @stored_procedure_name sysname
AS
BEGIN
    ...

    EXEC @stored_procedure_name @varchar1 @varchar2;
END

【问题讨论】:

  • 为了让超级狡猾的 sp 不那么狡猾,您可以添加一些验证以确保 @spname 是“合法的”。
  • 这就是我感到困惑的地方。由于超级狡猾只是使用参数,这可能是一个参数化查询,在这种情况下你不能注入 SQL 代码。所以它一点也不狡猾,你也不需要验证。
  • 你不能用EXEC @sp @param注入代码。您只能提供对不同 SP 的引用。这是微妙的不同。我不太同意 dknaack 的回答,所以我添加了自己的。我希望它有帮助:)
  • 太棒了 - 这回答了我试图解决的实际问题。但我会离开并尝试我自己的一些 SQL 注入来确认。我添加了对 sys.procedures 的检查(如您的第一条评论),但只是为了防止 SQL 注入!

标签: sql stored-procedures dynamic-sql


【解决方案1】:
EXEC [dbo].[my_really_special_sp] @varchar1 @varchar2;

不是参数化查询,它是存储过程的正常调用。

这取决于[my_really_special_sp] 的内容是否会导致参数化查询。

请提供更多信息,我愿意为您提供更多帮助。

【讨论】:

  • 感谢@dknaack,很抱歉含糊其辞,但我想弄清楚我的编程风格是否存在严重问题。通常 my_really_special_sp 将类似于 UPDATE [my_table] SET [field1] = @varchar1 WHERE [field2] = @varchar2
  • 我有一个版本可以正常工作并且没有任何操作。 UPDATE [my_table] SET [field1] = @varchar1 WHERE [field2] = @varchar2 是参数化查询吗?
  • 您应该使用第一种方法以获得更好的可读性、更好的测试和最重要的...更少的调用(更好的性能)。
  • 是的,99% 的时候我都会这样做。但如果我之前评论中的 UPDATE 语句被认为是“参数化”,我仍然感到困惑。
  • 假设我明白你的意思 ;) UPDATE [my_table] SET [field1] = @varchar1 WHERE [field2] = @varchar2 是参数化的
【解决方案2】:

“动态 SQL”是指以编程方式构建 SQL 查询字符串。比如添加join,建立where子句等。

参数化查询是包含变量的 SQL 查询字符串,其值与 SQL 查询字符串分开提供。

您的示例都不符合这些描述,因为它们都是存储过程中的简单 T-SQL 调用。


这可能看起来很迂腐,但如果您的应用程序调用 'EXEC [dbo].[my_really_special_sp] @varchar1 @varchar2',那么 that 就是一个参数化查询。

如果你的 SP 调用 sp_executesql 'EXEC [dbo].[my_really_special_sp] @var1 @var2', @var1 = 1, @var2 = 10 然后...

  • sp_executesql 是 T-SQL 调用
  • 'EXEC [dbo].[my_really_special_sp] @var1 @var2' 是您的参数化查询
  • @var1 = 1, @var2 = 10 是你的参数


重要的一点是您的示例是 SP 中的预编译语句。我试图解释的示例是 strings,它们被传递给 SQL Server 进行解析、编译和执行。

如果该字符串以编程方式逐段组成,则它是动态 sql。

如果该字符串包含单独提供的变量引用,则将其参数化。


我希望这会有所帮助,尽管我可以看到它可能看起来很主观。


至于你的编程风格。您的第二个 SP 有一个较小的“漏洞”,即如果用户可以访问它,他们就可以访问具有相同签名的所有其他 SP,即使该用户本身通常没有访问权限。这可能是故意的,和/或您可以验证@spname 参数以关闭漏洞。除此之外,我看不出有什么可以出错的。

【讨论】:

  • 太棒了,我喜欢迂腐,它解决了很多困惑 :) 这是迄今为止对差异最清晰的描述。
猜你喜欢
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
  • 2017-09-10
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多