a) 我们认为什么是动态 sql 语句?
任何动态添加子句甚至只是子句的一部分到 SQL 字符串的 sql 语句?
b)那么使用占位符来动态提供值的参数化字符串是否也被视为动态 sql 语句?
谢谢
a) 我们认为什么是动态 sql 语句?
任何动态添加子句甚至只是子句的一部分到 SQL 字符串的 sql 语句?
b)那么使用占位符来动态提供值的参数化字符串是否也被视为动态 sql 语句?
谢谢
动态 SQL 语句是在执行时构建的语句。重点在于陈述。因此,如果您只是在执行时提供一个值,它就不是动态 SQL 。
当然,任何涉及EXEC (@sql)
或EXEC sp_ExecuteSQL @sql, ...
(即数据库本身的动态)都符合条件,但我想您可能会争辩说,在运行时生成的任何 SQL(而不是在构建/安装时固定)都符合条件。
所以是的,您可能会争辩说,运行时生成但正确参数化的查询是“动态的”(例如,LINQ-to-SQL 生成的查询),但老实说,只要它不会让您受到注入攻击我不在乎名字;-p
动态 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。
动态 sql 基本上只是在运行时才完全构造的任何 sql。它通过将运行时值连接到语句中即时生成。可以是 sql 语句的任何部分
A. 任何会导致数据库服务器将字符串评估为 SQL 的东西。
B. 不,因为它们仍然通过 DB 驱动程序/提供程序进行清理。
对于点 b) 您已经知道该语句并传入已知参数(希望键入安全而不是字符串文字)。
我知道你要做什么,但是一个有点客观的标准将特定情况定义为动态 SQL 与说准备好的语句是......
...动态语句导致 SQL 服务器完全评估查询、定义查询计划等的事实。
使用准备好的语句,SQL 可以(除非明确要求)缓存查询计划(在某些情况下,甚至收集有关返回的统计信息等)。
[编辑:实际上,即使是动态 SQL 语句也会被缓存,但是这种缓存的计划被重用的机会要小得多,因为需要重新接收完全相同的查询才能发生这种情况(与参数化查询不同,其中计划甚至被重用)具有不同的参数值,当然,除非“重新编译”)]
因此,在问题的情况下,a) 和 b) 都将被视为动态 SQL,因为在 b) 的情况下,替换发生在 SQL 之外。这不是一个准备好的声明。SQL 将其视为一个全新的语句,因为它不知道您只是在更改搜索值。
现在......除了动态 SQL的以 SQL 为中心的定义之外,区分各种形式的动态 SQL 可能很有用,例如你的 a) 和 b) 情况。
一段时间以来,动态 SQL 的名声不好,其中一些与 SQL 注入意识有关。我已经看到在存储过程中生成和执行动态 SQL 的应用 程序,并且因为它在技术上是“SQL 端”的,所以有些人倾向于接受它(即使可能没有特别解决 SQL 注入问题)。 ..
我在这里要说明的一点是,通常需要从各种上下文元素动态构建查询,最好建议在“应用程序”层中实现这一点(好吧,称之为应用程序端层,例如事实上,它可以而且应该与应用程序本身分开),其中编程语言和相关的数据结构通常比 T-SQL 等更容易和更具表现力。因此,在我看来,为了称其为“数据端”而将其插入 SQL 并不是一件好事。
我认为动态 SQL 语句是在运行时接受新值以返回不同结果的语句。我认为“新值”可以是不同的 ORDER BY、新的 WHERE 标准、不同的字段选择等。
a) 我们认为什么是动态 sql 语句?任何动态添加子句甚至只是子句的一部分到 SQL 字符串的 sql 语句?
两者 - 在执行之前更改/定制的任何查询。
b)那么使用占位符来动态提供值的参数化字符串是否也被视为动态 sql 语句?
参数化查询,AKA 使用绑定变量,为查询提供不同的过滤条件。您可以使用(my_variable IS NULL OR ...)
,但 OR 性能在任何数据库上通常都很糟糕,并且该方法会破坏 sargability。
动态 SQL 通常处理定制查询以包含其他逻辑,例如仅在设置特定参数时才需要包含的 JOIN。但是,存在一些限制,例如 IN 子句不支持将逗号分隔的字符串转换为选项列表 - 为此,您必须使用动态 SQL,或以另一种方式处理逗号分隔列表(CLR,流水线化到临时表中, ETC)。