所谓SQL的静态和动态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程。
二者区别 :
静态SQL | 动态SQL |
SQL语句直接嵌入到宿主编程语言,程序需要预编译处理这些嵌入的SQL语句 | SQL语句一般作为宿主语言的变量出现。嵌入式动态SQL应用需要预编译,非嵌入式SQL应用则无需预编译 |
SQL语句在程序被编译时已知,涉及的数据库对象已存在 | SQL语句在程序被编译时未知,涉及的数据库对象可以是运行时才创建的 |
SQL语句在程序运行前被编译 | SQL语句在程序运行时被编译 |
SQL语句的编译结果在DB2的目录(catalog)中持久化保存 | SQL语句的编译结果缓存在数据库的内存里 |
运行时读取目录(catalog) | 运行时编译SQL语句需要对目录(catalog)加锁 |
SQL语句的优化是根据编译时的数据库统计信息进行的,不能完全反映运行时的情况 | SQL语句的优化是根据运行时的数据库统计信息进行的 |
对SQL语句所访问的数据对象的权限检查是在绑定时进行的 | 对SQL语句所访问的数据对象的权限检查是在运行时进行的 |
权限控制的粒度是包(package,一组SQL语句的编译结果),用户仅需要访问包的权限 | 权限控制的粒度是SQL语句,用户需要具有访问SQL语句中每个数据对象的权限 |
如果SQL语句中的对象被绑定,如DDL执行,整个包都需要重新绑定 | 当SQL语句中的对象被修改时,仅执行过的语句在下次运行时需要重新编译 |
静态SQL
在某种高级语言中,如果嵌入了SQL语句,而这个SQL语句的主体结构已经明确,例如在Java的一段代码中有一个待执行的SQL“select * from t1 where c1>5”,在Java编译阶段,就可以将这段SQL交给数据库管理系统去分析,数据库软件可以对这段SQL进行语法解析,生成数据库方面的可执行代码,这样的SQL称为静态SQL,即在编译阶段就可以确定数据库要做什么事情。
动态SQL
而如果嵌入的SQL没有明确给出,如在Java中定义了一个字符串类型的变量sql:String sql;,然后采用preparedStatement对象的execute方法去执行这个sql,该sql的值可能等于从文本框中读取的一个SQL或者从键盘输入的SQL,但具体是什么,在编译时无法确定,只有等到程序运行起来,在执行的过程中才能确定,这种SQL叫做动态SQL。例如每一种数据库软件都有能够执行SQL语句的界面,那个界面接收的SQL就是动态SQL,因为数据库厂商在做这个界面时,并不知道用户会输入哪些SQL,只有在该界面执行后,接收了用户的实际输入,才知道SQL是什么。
另外还要注意一点,在SQL中如果某些参数没有确定,如"select * from t1 where c1>? and c2<?",这种语句是静态SQL,不是动态SQL,虽然个别参数的值不知道,但整个SQL的结构已经确定,数据库是可以将它编译的,在执行阶段只需将个别参数的值补充进来即可。