【发布时间】:2009-01-20 19:26:57
【问题描述】:
SO 有很多关于如何使用动态 SQL 完成各种任务的问答,回复中经常伴随着警告和免责声明,说明实际使用所提供方法的可取性。我曾在从“知道如何使用游标是一个坏兆头”到“sp_executesql 不整洁!”的环境中工作过。
当涉及到生产系统时,应该始终避免使用动态 sql,或者它应该在编程工具箱中占有一席之地。如果不是/那么,为什么?
【问题讨论】:
标签: sql
SO 有很多关于如何使用动态 SQL 完成各种任务的问答,回复中经常伴随着警告和免责声明,说明实际使用所提供方法的可取性。我曾在从“知道如何使用游标是一个坏兆头”到“sp_executesql 不整洁!”的环境中工作过。
当涉及到生产系统时,应该始终避免使用动态 sql,或者它应该在编程工具箱中占有一席之地。如果不是/那么,为什么?
【问题讨论】:
标签: sql
您的一些问题的答案可以在这里找到The Curse and Blessings of Dynamic SQL
有时您必须使用动态 SQL,因为它的性能会更好
【讨论】:
这取决于你所说的动态 sql 是什么意思。将参数值直接替换到 sql 字符串中的查询是危险的,应该避免,除非在极少数情况下没有其他选项。
使用您的平台支持的适当参数化查询机制的动态 SQL 可能非常强大。
【讨论】:
在评估动态 SQL 的使用时有几个注意事项:
请记住,SQL 是代码,RDBMS 是另一个 API。它并不特别,或者至少不多;像处理任何其他代码和 API 一样处理它。特别是,不要只针对 API 直接编写代码:将代码模块化并编写一些辅助方法以使其更容易和可重用。
【讨论】:
“动态 SQL”的成本因 DBMS 而异。
在 IBM DB2 中,查询计划可以预编译为机器代码,动态 SQL 的成本很高。
在 IBM Informix (IDS - Informix Dynamic Server) 中,大多数查询实际上是“动态 SQL”(存储过程中的查询除外),因为 SQL 在运行时被解释,即使客户端-旁注使用静态 SQL。
我相信 - 尽管 DB2 专家可能会反驳我 - DB2 的 CLI(ODBC,又名 CCC)和 JCC (JDBC) 系统将所有 SQL 作为动态 SQL 执行。
我不知道 Oracle、Sybase、MS SQL Server 是做什么的——我怀疑它们更接近 IDS 采用的线路而不是 DB2 采用的线路。对于 MySQL 和 PostgreSQL,如果它们的行为不像 DB2 那样更像 IDS,我会感到惊讶。
因此,对于 IDS,使用动态 SQL 没有特别的开销;在服务器级别,您的 SQL 无论如何都是动态的。其他 DBMS 可能还有其他因素在起作用。
所有服务器的一个问题是“如何从通过网络发送的 SQL 中识别预编译查询”。对于 DB2,预编译器识别所使用的包,应用程序和服务器之间的通信协议识别它。我的理解是 ODBC 和 JDBC 等 DB2 客户端不使用预编译包 - 因此我认为它们一直有效地执行动态 SQL。
当心动态 SQL 的 SQL 注入!
【讨论】:
我以前的商店永远不会允许对数据库(SQL Server)执行这样的事情。 它被禁止作为实践,并且数据库被锁定以防止它。 所有工作都通过对象(SP 等)进行。
这是正确的做法,恕我直言。
【讨论】:
在某些极端情况下,动态 SQL 比替代方法更容易、更快。只要您保持它们的数量很少而且它们之间的距离很远,并且它们是动态生成的准备好的参数化 SQL,我认为它们没有什么大问题。
【讨论】:
动态 SQL 占有一席之地 - 即使在生产代码中也是如此。执行带有安全漏洞的任意代码不会。
一般来说,如果没有充分的理由使用动态 SQL,我会避免使用它。动态 SQL 在运行之前不会被检查,因此您显然有更大的测试负担。但是,在处理管理任务、静态代码生成、适应不断变化的系统而无需基于查询元数据进行过多维护、使用 DRY 避免冗余等时,有很多好时机使用它。
【讨论】:
我认为我们的系统中有很多动态 SQL,主要是因为我们有很多动态创建的对象(主要是表、索引、视图)。其中很多是遗产。诸如 2k5 中的分区表之类的东西在我们的一些用例中有所帮助。但是如前所述,您需要为此做好充分的准备; procs 中的 on-the-fly SQL 通常有更好的(静态)解决方案。
【讨论】: