第 16 章 动态sql
16.1 为何使用动态sql
实现动态sql有两种方式:dbms_sql和本地动态sql(execute immeidate)
主要从以下方面考虑使用哪种方式:
1. 是否知道涉及的列数和类型
dbms_sql包括了一个可以“描述”结果集的存储过程(dbms_sql.describe_columns),而本地动态sql没有。
2. 是否知道可能涉及的绑定变量数和类型
dbms_sql允许过程化的绑定语句的输入,而本地动态sql需要在编译时确定。
3. 是否使用“数组化”操作(array processing)
dbms_sql允许,而本地动态sql基本不可以,但可以用其他方式实现(对查询可用fetch bulk collect into,对insert等,可用一个begin … end块中加循环实现)。
4. 是否在同一个会话中多次执行同一语句
dbms_sql可以分析一次执行多次,而本地动态sql会在每次执行时进行软分析。
5. 是否需要用ref cursor返回结果集
仅本地动态sql可用ref cursor返回结果集。
16.2 如何使用动态sql
dbms_sql
1. 调用open_cursor获得一个游标句柄;
2. 调用parse分析语句。一个游标句柄可以用于多条不同的已分析语句,但一个时间点仅一条有效;
3. 调用bind_variable或bind_array来提供语句的任何输入;
4. 若是一个查询(select语句),调用difine_column或define_array来告知oracle如何返回结果;
5. 调用execute执行语句;
6. 若是一个查询,调用fetch_rows来读取数据。可以使用column_value从select列表根据位置获得这些值;
7. 否则,若是一个pl/sql块或带有return子句的dml语句,可以调用variable_value从块中根据变量名获得out值;
8. 调用close_cursor.
注意这里对任何异常都应该处理,以关闭游标,防止泄露资源。
本地动态sql
execute immediate ‘语句’
[into {变量1, 变量2, … 变量n | 记录体}]
[using [in | out | in out] 绑定变量1, … 绑定变量n]
[{returning | return} into 输出1 [, …, 输出n]…];
注意本地动态sql仅支持弱类型ref cursor,即对于ref cursor,不支持bulk collect.
16.3 最后说明
动态sql的负面:破坏了依赖链、代码更脆弱、很难调优。
16.1 为何使用动态sql
实现动态sql有两种方式:dbms_sql和本地动态sql(execute immeidate)
主要从以下方面考虑使用哪种方式:
1. 是否知道涉及的列数和类型
dbms_sql包括了一个可以“描述”结果集的存储过程(dbms_sql.describe_columns),而本地动态sql没有。
2. 是否知道可能涉及的绑定变量数和类型
dbms_sql允许过程化的绑定语句的输入,而本地动态sql需要在编译时确定。
3. 是否使用“数组化”操作(array processing)
dbms_sql允许,而本地动态sql基本不可以,但可以用其他方式实现(对查询可用fetch bulk collect into,对insert等,可用一个begin … end块中加循环实现)。
4. 是否在同一个会话中多次执行同一语句
dbms_sql可以分析一次执行多次,而本地动态sql会在每次执行时进行软分析。
5. 是否需要用ref cursor返回结果集
仅本地动态sql可用ref cursor返回结果集。
16.2 如何使用动态sql
dbms_sql
1. 调用open_cursor获得一个游标句柄;
2. 调用parse分析语句。一个游标句柄可以用于多条不同的已分析语句,但一个时间点仅一条有效;
3. 调用bind_variable或bind_array来提供语句的任何输入;
4. 若是一个查询(select语句),调用difine_column或define_array来告知oracle如何返回结果;
5. 调用execute执行语句;
6. 若是一个查询,调用fetch_rows来读取数据。可以使用column_value从select列表根据位置获得这些值;
7. 否则,若是一个pl/sql块或带有return子句的dml语句,可以调用variable_value从块中根据变量名获得out值;
8. 调用close_cursor.
注意这里对任何异常都应该处理,以关闭游标,防止泄露资源。
本地动态sql
execute immediate ‘语句’
[into {变量1, 变量2, … 变量n | 记录体}]
[using [in | out | in out] 绑定变量1, … 绑定变量n]
[{returning | return} into 输出1 [, …, 输出n]…];
注意本地动态sql仅支持弱类型ref cursor,即对于ref cursor,不支持bulk collect.
16.3 最后说明
动态sql的负面:破坏了依赖链、代码更脆弱、很难调优。
本文介绍了动态SQL的两种实现方式:dbms_sql和本地动态SQL(execute immediate),并详细阐述了选择不同方式时需要考虑的因素。此外,还提供了这两种方式的具体使用步骤,并讨论了动态SQL可能带来的负面影响。

185

被折叠的 条评论
为什么被折叠?



