我们认为什么是动态sql语句?

时间:2009-12-10 20:22:54

标签: sql dynamic-sql

a)我们认为什么是动态sql语句?  是否有任何sql语句可以动态地将子句或子句的一部分添加到SQL字符串中?

b)那么对动态提供的值使用占位符的参数化字符串是否也被视为动态sql语句?

感谢名单

9 个答案:

答案 0 :(得分:6)

动态SQL语句是在执行时构建的语句。重点在于声明。因此,如果您只是在执行时提供,那么它不是动态SQL。

答案 1 :(得分:3)

当然任何涉及EXEC (@sql)EXEC sp_ExecuteSQL @sql, ...的东西(即数据库本身都是动态的)都有资格,但我想你可能会争辩说在运行时生成的任何SQL(而不是在build / install中修复)都会出线。

所以是的,您可能会认为运行时生成但正确参数化的查询是“动态的”(例如,LINQ-to-SQL生成的查询),但说实话,只要它不会让您暴露注射攻击我不在乎名字;-p

答案 2 :(得分:3)

动态SQL语句通常是指使用字符串连接构造的语句。

"SELECT name FROM names WHERE id=" + this.id;
"SELECT name FROM names WHERE id=" + this.id + " AND age=" this.age;

参数化查询也是动态的,但不是构造方面的。您只能更改参数,但不能更改语句的结构,即添加WHERE子句。

参数化查询通常位于数据库级别,因此数据库可以缓存查询的执行计划并反复使用它。在第一种情况下不太可能,因为文本的简单更改或where子句的顺序可能导致数据库无法识别先前缓存的执行计划并重新开始。

第一个构造也容易受到SQL注入攻击,因为很难验证注入流氓SQL的尝试的输入值。

答案 3 :(得分:2)

动态sql基本上只是在运行时才完全构造的任何sql。它通过将运行时值连接到语句中而即时生成。可以是sql语句的任何部分

答案 4 :(得分:1)

一个。任何会导致DB服务器将字符串计算为SQL的东西。

B中。不,因为他们仍然通过数据库驱动程序/提供程序并进行清理。

答案 5 :(得分:1)

对于b)点你已经知道了这个语句并传入了已知的参数(希望是类型安全而不是字符串文字)。

答案 6 :(得分:1)

我知道你要去哪里,但是有一个客观的标准,它将特定情况定义为动态SQL而不是准备好的声明......

... 动态语句使SQL服务器完全评估查询,定义查询计划等事实。

使用预准备语句,SQL可以(除非明确要求)缓存查询计划(在某些情况下,甚至可以收集有关返回的统计信息等)。
[编辑:有效地,甚至动态SQL语句都被缓存,但是这样的缓存计划被重用的可能性要小得多,因为需要重新接收完全相同的查询才能实现这一点(与参数化不同)即使使用不同的参数值,也可以查询计划的重复使用情况,当然,除非“WITH RECOMPILE”)]

因此,在问题的情况下,a)和b)都将被视为动态SQL,因为在b)的情况下,替换发生在SQL之外。这不是一份准备好的声明。 SQL会将其视为一个完全新颖的陈述,因为它不知道您只是在改变搜索值。

现在......除了动态SQL的 以SQL为中心的定义之外,区分各种形式的动态SQL可能很有用,比如说你的a) b)案例。一段时间以来,动态SQL有一个糟糕的代表,其中一些与SQL注入意识有关。我已经看到了动态SQL生成和执行的应用程序,存储过程中,并且因为它在技术上是“SQL端”,所以有些人倾向于接受它(即使特别是SQL注入可能没有得到解决)...
我试图在这里提出的观点是,通常需要动态地从各种上下文元素构建查询,并且最好建议在“应用程序”层中实现这一点(好吧,称之为应用程序端层,事实上,它可以而且应该与应用程序本身分开,其中编程语言和相关数据结构通常比T-SQL等更容易和更具表现力。因此,为了将其称为“数据端”而将其干扰到SQL中并不是一件好事,在我看来。

答案 7 :(得分:1)

我认为动态SQL语句是在运行时接受新值以便返回不同结果的语句。根据我的推算,“新价值”可以是不同的ORDER BY,新的WHERE标准,不同的字段选择等。

答案 8 :(得分:1)

  

a)我们认为什么是动态sql语句?   是否有任何sql语句可以动态地将子句或子句的一部分添加到SQL字符串中?

两者 - 在执行之前更改/定制的任何查询。

  

b)那么对动态提供的值使用占位符的参数化字符串是否也被视为动态sql语句?

参数化查询,使用绑定变量的AKA,为查询提供不同的过滤器标准。您可以使用(my_variable IS NULL OR ...),但在任何数据库和数据库中,OR性能通常很糟糕。这种方法破坏了sargability。

动态SQL通常涉及定制查询以包含其他逻辑,例如只有在设置特定参数时才需要包含的JOIN。但是,有一些限制,例如IN子句不支持将逗号分隔的字符串转换为选项列表 - 为此,您必须使用动态SQL,或以另一种方式处理逗号分隔列表(CLR,流水线化为临时表,等)。