`

Oracle 绑定变量

阅读更多
在oracle 中,对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析,一种叫做软解析.
一个硬解析需要经解析,制定执行路径,优化访问计划等许多的步骤.硬解释不仅仅耗费大量的cpu,更重要的是会占据重要的们闩(latch)资源,严重的影响系统的规模的扩大(即限制了系统的并发行), 而且引起的问题不能通过增加内存条和cpu的数量来解决。之所以这样是因为门闩是为了顺序访问以及修改一些内存区域而设置的,这些内存区域是不能被同时修改。当一个sql语句提交后,oracle会首先检查一下共享缓冲池(shared pool)里有没有与之完全相同的语句,如果有的话只须执行软分析即可,否则就得进行硬分析。
 而唯一使得oracle 能够重复利用执行计划的方法就是采用绑定变量。绑定变量的实质就是用于替代sql语句中的常量的替代变量。绑定变量能够使得每次提交的sql语句都完全一样。
普通sql语句:
SELECT fname, lname, pcode FROM cust WHERE id = 674;
SELECT fname, lname, pcode FROM cust WHERE id = 234;
SELECT fname, lname, pcode FROM cust WHERE id = 332;
含绑定变量的sql 语句:
SELECT fname, lname, pcode FROM cust WHERE id = :cust_no;
 
Sql*plus 中使用绑定变量:
sql> variable x number;
sql> exec :x := 123;
sql> SELECT fname, lname, pcode FROM cust WHERE id =:x;
 
pl/sql
 pl/sql很多时候都会自动绑定变量而无需编程人员操心,即很多你写得sql语句都会自动利用绑定变量,如下例所示:
create or replace procedure dsal(p_empno in number)
as
  begin
    update emp
    set sal=sal*2
    where empno = p_empno;
    commit;
  end;
/
也许此时你会想要利用绑定变量来替代p_empno,但是这是完全没有必要的,因为在pl/sql中,引用变量即是引用绑定变量。
但是在pl/sql中动态sql并不是这样。
在vb,java以及其他应用程序中都得显式地利用绑定变量。
对于绑定变量的支持不仅仅限于oracle,其他RDBMS向SQLSERVER也支持这一特性。
但是并不是任何情况下都需要使用绑定变量, 下面是两种例外情况:
1.对于隔相当一段时间才执行一次的sql语句,这是利用绑定变量的好处会被不能有效利用优化器而抵消
2.数据仓库的情况下。

 

以下介绍几种情况:

1.让Oracle自己绑定变量
set serverout on;
set timing on;
declare
l_sql varchar2(2000);
l_count number;
l_param1 varchar2(100);
l_param2 varchar2(100);
begin
l_param1:=’a';
l_param2:=’b';
select count(*) into l_count from table1 where col_1=l_param1 and col_2=l_param2;
dbms_output.put_line(l_count);
end;
/
在上面的情况,Oracle会自己绑定变量,即,如果参数保存在一个数组中,select语句放在一个循环中,
select 语句只会编译一次。
像这样
for i in 1..3
loop
select count(*) into l_count from table1 where col_1=l_param1 and col_2=l_param2 and col_3=i;
dbms_output.put_line(l_count);
end loop

2.不绑定变量
set serverout on;
set timing on;
declare
l_sql varchar2(2000);
l_count number;
l_param1 varchar2(100);
l_param2 varchar2(100);
begin
l_param1:=’a';
l_param2:=’b';
l_sql:=’select count(*) into :x from table1 where col_1=’||l_param1||’ and col_2=’||l_param2;
Execute Immediate l_sql into l_count;
dbms_output.put_line(l_count);
end;
/
3.动态绑定变量
set serverout on;
set timing on;
declare
l_sql varchar2(2000);
l_count number;
l_param1 varchar2(100);
l_param2 varchar2(100);
begin
l_param1:=’a';
l_param2:=’b';
l_sql:=’select count(*) into :x from table1 where col_1=:y and col_2=:z ’;
Execute Immediate l_sql into l_count using l_param1,l_param2;
dbms_output.put_line(l_count);
end;
/

:x,:y,:z相当于占位符,即
1.用:p1,:p2,:p3是一样的。
2.用:x,:x,:x也是一样的
需要的绑定变量按顺序排在执行语句后面就可以了,into的除外。
不过还是用p1,p2好些,至少可以看出绑定了多少个变量。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics