4、在动态SQL中是使用绑定变量
[sql] view plaincopyprint?
-->动态SQL中不能自动使用绑定变量,需要手动设定绑定变量
SQL> @get_parse -->获得当前hard parse解析情况,此时为120
NAME VALUE
------------------------- ----------
parse count (total) 533
parse count (hard) 120
parse count (failures) 1
SQL> begin
2 for i in 1..30 loop
3 execute immediate 'insert into t values(:1,:2)' using i,i+i-2; -->动态SQL使用绑定变量,该语句将执行30次
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> @get_parse --> 动态SQL执行后,尽管执行了30次,但硬解析数量仅仅增加了2次
NAME VALUE
------------------------- ----------
parse count (total) 537
parse count (hard) 122
parse count (failures) 1
SQL> set serveroutput on;
SQL> get get_sal.sql -->下面的pl/sql中使用了绑定变量
1 DECLARE
2 TYPE emp_cur IS REF CURSOR;
3 my_emp_cur emp_cur;
4 my_emp_rec emp%ROWTYPE;
5 BEGIN
6 OPEN my_emp_cur FOR 'select * from emp where deptno=:dno' USING 10;
7 LOOP
8 FETCH my_emp_cur INTO my_emp_rec;
9 EXIT WHEN my_emp_cur%NOTFOUND;
10 dbms_output.put_line(my_emp_rec.ename||'''s salary is : '||my_emp_rec.sal);
11 END LOOP;
12* END;
13 /
CLARK's salary is : 4900
KING's salary is : 5000
MILLER's salary is : 1300
PL/SQL procedure successfully completed.
SQL> /
CLARK's salary is : 4900
KING's salary is : 5000
MILLER's salary is : 1300
PL/SQL procedure successfully completed.
SQL> select sql_text,executions,sql_id from v$sqlarea where sql_text like 'select * from emp where deptno=:dno%';
SQL_TEXT EXECUTIONS SQL_ID
--------------------------------------------- ---------- -------------
select * from emp where deptno=:dno 2 c1nx6x02h655a
-->动态SQL中不能自动使用绑定变量,需要手动设定绑定变量
SQL> @get_parse -->获得当前hard parse解析情况,此时为120
NAME VALUE
------------------------- ----------
parse count (total) 533
parse count (hard) 120
parse count (failures) 1
SQL> begin
2 for i in 1..30 loop
3 execute immediate 'insert into t values(:1,:2)' using i,i+i-2; -->动态SQL使用绑定变量,该语句将执行30次
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> @get_parse --> 动态SQL执行后,尽管执行了30次,但硬解析数量仅仅增加了2次
NAME VALUE
------------------------- ----------
parse count (total) 537
parse count (hard) 122
parse count (failures) 1
SQL> set serveroutput on;
SQL> get get_sal.sql -->下面的pl/sql中使用了绑定变量
1 DECLARE
2 TYPE emp_cur IS REF CURSOR;
3 my_emp_cur emp_cur;
4 my_emp_rec emp%ROWTYPE;
5 BEGIN
6 OPEN my_emp_cur FOR 'select * from emp where deptno=:dno' USING 10;
7 LOOP
8 FETCH my_emp_cur INTO my_emp_rec;
9 EXIT WHEN my_emp_cur%NOTFOUND;
10 dbms_output.put_line(my_emp_rec.ename||'''s salary is : '||my_emp_rec.sal);
11 END LOOP;
12* END;
13 /
CLARK's salary is : 4900
KING's salary is : 5000
MILLER's salary is : 1300
PL/SQL procedure successfully completed.
SQL> /
CLARK's salary is : 4900
KING's salary is : 5000
MILLER's salary is : 1300
PL/SQL procedure successfully completed.
SQL> select sql_text,executions,sql_id from v$sqlarea where sql_text like 'select * from emp where deptno=:dno%';
SQL_TEXT EXECUTIONS SQL_ID
--------------------------------------------- ---------- -------------
select * from emp where deptno=:dno 2 c1nx6x02h655a
三、绑定变量的优缺点及使用场合
优点:
可以在library cache中共享游标,避免硬解析以及与之相关的额外开销
在大批量数据操作时将呈数量级来减少闩锁的使用,避免闩锁的竞争
缺点:
绑定变量被使用时,查询优化器会忽略其具体值,因此其预估的准确性远不如使用字面量值真实,尤其是在表存在数据倾斜(表上的数
据非均匀分布)的列上会提供错误的执行计划。从而使得非高效的执行计划被使用。
使用场合:
OLTP
在OLTP系统中SQL语句重复执行频度高,但处理的数据量较少,结果集也相对较小,尤其是使用表上的索引来缩小中间结果集,其
解析时间通常会接近或高于执行时间,因此该场合适合使用绑定变量。
OLAP
在OLAP系统中,SQL语句执行次数相对较少,但返回的数据量较大,因此多数情况下倾向于使用权标扫描更高效,其SQL语句执行时
间远高于其解析时间,因此使用绑定变量对于总响应时间影响不大。而且增加生成低效执行计划的风险。即在在OLAP系统中使用字
面量的性能高于使用绑定变量。
注意:
对于实际的数据库对象,如(表,视图,列等),不能使用绑定变量替换,只能替换字面量。如果对象名是在运行时生成的,则需要对其
用字符串拼接,同时,sql只会匹配已经在共享池中相同的对象名。