生产系统中的动态SQL

时间:2009-01-20 19:26:58

标签: sql

SO有很多Q&关于如何使用动态SQL完成各种任务,响应通常伴随着关于实际使用所提供方法的可行性的警告和免责声明。我曾经在“知道如何使用光标是一个坏标志”到“不是sp_executesql整洁!”的环境中工作。

说到生产系统,应该始终避免使用动态sql,或者它应该在编程工具箱中具有有效位置。如果不是/为什么?

8 个答案:

答案 0 :(得分:7)

您可以在The Curse and Blessings of Dynamic SQL

找到有关您的一些问题的答案

有时你必须使用动态SQL,因为它会表现得更好

答案 1 :(得分:2)

这取决于动态sql的含义。在参数值直接替换为sql字符串的情况下构建的查询是危险的,应该避免,除非极少数情况下没有其他选项。

使用您的平台支持的适当参数化查询机制的动态SQL非常强大。

答案 2 :(得分:2)

评估动态SQL的使用时需要考虑几个因素:

  • 性能可能差别很大,具体针对哪个数据库引擎
  • 维护可以在两个方向上广泛变化(例如,动态SQL可以使用 静态SQL不能的模块化技术)
  • 动态SQL容易受到SQL注入攻击,但静态SQL(大部分)不是
  • 有时你的需求会使静态SQL(几乎)不可能,但这应该是罕见的

请记住,SQL是代码,RDBMS是另一种API。这不是特别的,或者至少不是很多;像处理任何其他代码和API一样处理它。特别是,不要直接针对API进行编码:模块化您的代码并编写一些帮助方法,以使其更容易和可重用。

答案 3 :(得分:1)

“动态SQL”的成本因DBMS而异。

  • 在IBM DB2中,可以将查询计划预编译为机器代码,动态SQL的成本非常高。

  • 在IBM Informix(IDS - Informix Dynamic Server)中,大多数查询实际上是“动态SQL”(存储过程中的查询除外),因为SQL在运行时被解释,即使客户端 - side表示法使用静态SQL。

我相信 - 虽然DB2专家可能会反驳我 - DB2的CLI(ODBC,又名CCC)和JCC(JDBC)系统将所有SQL都作为动态SQL。

我不知道Oracle,Sybase,MS SQL Server做了什么 - 我怀疑它们是否接近IDS采用的行而不是DB2采用的行。对于MySQL和PostgreSQL,如果他们的行为不像DB2那样我会感到惊讶。

因此,使用IDS,使用动态SQL没有特别的开销;在服务器级别,您的SQL无论如何都是动态的。其他DBMS可能还有其他因素在起作用。

所有服务器的一个问题是“如何识别通过网络发送的SQL的预编译查询”。使用DB2,预编译器识别所使用的包,应用程序和服务器之间的通信协议识别该包。我的理解是ODBC和JDBC之类的DB2客户端不使用预编译的包 - 因此我认为它们总是有效地执行动态SQL。

注意动态SQL的SQL注入!

答案 4 :(得分:0)

我以前的商店永远不会允许对数据库(SQL Server)执行此类操作。 它被禁止作为练习,数据库被锁定以防止它。 所有工作都通过对象(SP等)。

这是正确的做法,恕我直言。

答案 5 :(得分:0)

有一些边缘情况,动态SQL比替代方案更容易和更快。只要你保持它们之间的数量很少而且它们是动态生成的参数化SQL,我认为它们没有什么大问题。

答案 6 :(得分:0)

动态SQL有一席之地 - 即使在生产代码中也是如此。执行带有安全漏洞的任意代码不会。

一般情况下,如果没有充分的理由使用它,我会避免使用动态SQL。动态SQL在运行之前不会被检查,因此您显然会有更大的测试负担。但是,在处理管理任务,静态代码生成,适应不断变化的系统而不需要基于查询元数据的过度维护,使用DRY来避免冗余等等时,有很多好时机可以使用它。

答案 7 :(得分:0)

我们的系统中包含了很多动态SQL,主要是因为我们有很多动态创建的对象(主要是表,索引,视图)。其中很多是遗产;像2k5中的分区表这样的东西在某些用例中有所帮助。但如上所述,你需要为它做一个好的案例;在procs中的即时SQL通常有一个更好的(静态)解决方案。