Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1450153
  • 博文数量: 239
  • 博客积分: 5909
  • 博客等级: 大校
  • 技术积分: 2715
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-24 20:19
文章分类

全部博文(239)

文章存档

2014年(4)

2013年(22)

2012年(140)

2011年(14)

2010年(59)

我的朋友

分类: Oracle

2012-08-11 23:52:14

oracle 中,对于一个提交的sql语句,存在两种可选的解析过程一种叫做硬解析,一种叫做软解析.

一个硬解析需要经解析,制定执行路径,优化访问计划等许多的步骤.硬解释不仅仅耗费大量的cpu,更重要的是会占据重要的们闩(latch)资源,严重的影响系统的规模的扩大(即限制了系统的并发行),而且引起的问题不能通过增加内存条和cpu的数量来解决。之所以这样是因为门闩是为了顺序访问以及修改一些内存区域而设置的,这些内存区域是不能被同时修改。当一个sql语句提交后,oracle会首先检查一下共享缓冲池(shared pool)里有没有与之完全相同的语句,如果有的话只须执行软分析即可,否则就得进行硬分析。

 而唯一使得oracle 能够重复利用执行计划的方法就是采用绑定变量。绑定变量的实质就是用于替代sql语句中的常量的替代变量。绑定变量能够使得每次提交的sql语句都完全一样。

 

1.

sqlplus中如何使用绑定变量,可以通过variable来定义

  1. SQL> variable i number;  
  2. SQL> exec :i :=1;  
  3.   
  4. PL/SQL 过程已成功完成。  
  5.   
  6. SQL> select *from tt where id=:i;  

2.

前两天看到有人在pub上问sqlplus中通过definevariable定义的变量的区别。其实define定义的我
理解不是变量而是字符常量,通过define定义之后,在通过&或者&&引用的时候不需要输入了,仅此而已。
oracle
在执行的时候自动用值进行了替换;而variable定义的是绑定变量,上面已经提到。 &和&&的区别是每次使用&时都会重新询问,而&&会一直使用一个值。

  1. SQL> define a=1  
  2. SQL> define  
  3. SQL> select * from tt where id=&a; 
  4. select * from tt where id=&&a;
  5. define b='a';
  6. select * from tt where name='&&b'
  7. select * from tt where name='&b';

3.

oracle在解析sql时会把plsql中定义的变量转为为绑定变量

  1. SQL> declare  
  2. 2 begin  
  3. for i in 1..100 loop  
  4. 4 insert into tt values(i,'test');  
  5. 5 end loop;  
  6. 6 commit;  
  7. 7 end;  
  8. 8 /  

4.

过程中的参数会自动转化为绑定变量

  1. 1 create or replace procedure proc_test(p_id int, p_name varchar2)  
  2. is  
  3. 3 begin  
  4. 4 insert into tt values(p_id , p_name);  
  5. 5 commit;  
  6. 6* end;  
  7. SQL> /  
  8. SQL> exec proc_test(200,'test');  

5.

在动态sql中使用绑定变量,动态sql中使用绑定变量非常明显也容易理解,

  1. SQL> set serveroutput on  
  2. SQL> declare  
  3.    2   v_string varchar2(100);  
  4.    3   v_id tt.id%type ;  
  5.    4   v_name tt.name%type ;  
  6.    5   begin  
  7.    6   v_string:='select * from tt where id=:v_id';  
  8.    7   execute immediate v_string into v_id , v_name using &a;  
  9.    8   dbms_output.put_line(v_id||' '||v_name) ;  
  10.    9   end;  
  1. SQL> declare  
  2.    2   v_string varchar2(100);  
  3.    3   v_id tt.id%type;  
  4.    4   v_name tt.name%type ;  
  5.    5   begin  
  6.    6   v_string:='insert into tt values(:id,:name)';  
  7.    7   execute immediate v_string using &id,&name ;  
  8.    8   end;  
  9.    9   /  

&替换变量)
  1. SQL> select xh,xm from system.xs where zym='&zym';  如果zym没有定义
  2. 输入 zym 的值:   
&&替换变量
  1. --&&替换变量系统一直用同一个值处理,清除用undefine 变量名清除  
  2. SQL> edit  
  3. 已写入 file afiedt.buf  
  4.   
  5.   1  select xs.xh,&name,kcm,&&column   /*清除替换变量(undefine column)*/  
  6.   2  from system.xs,&kc,system.xs_kc  
  7.   3  where xs.xh=xs_kc.xh and &condition  
  8.   4  and kcm=&kcm  
  9.   5* order by &column  
  10. SQL> /    /*column的值只会提示输入一次*/
ACCEPT variable[datatype[NUMBER|CHAR|DATE]][FORMAT format][PROMPT text][HIDE]/*variable:指定接收值的变量。该名称的变量不存在,那么SQL重建该变量;datatype:变量数据类型,默认为CHAR*/
  1. SQL> accept num prompt'请输入课程号:'  
  2. 请输入课程号:101  
  3. SQL> set verify on  

阅读(951) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~