ORACLE 绑定变量用法总结

http://blog.csdn.net/wh62592855/archive/2009/11/06/4778343.aspx

之前对ORACLE中的变量一直没个太清楚的认识,比如说使用:、&、&&、DEIFINE、VARIABLE……等等。今天正好闲下来,上网搜了搜相关的文章,汇总了一下,贴在这里,方便学习。

==================================================================================


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

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

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

 


1.


sqlplus中如何使用绑定变量,可以通过variable来定义
view plaincopy to clipboardprint?
01.SQL> select * from tt where id=1;  
02. 
03.ID NAME  
04.---------- ----------------------------------------  
05.1 test  
06. 
07.SQL> select * from tt where id=2;  
08. 
09.ID NAME  
10.---------- ----------------------------------------  
11.2 test  
12. 
13.SQL> variable i number;  
14.SQL> exec :i :=1;  
15. 
16.PL/SQL 过程已成功完成。  
17. 
18.SQL> select *from tt where id=:i;  
19. 
20.ID NAME  
21.---------- ----------------------------------------  
22.1 test  
23. 
24.SQL> exec :i :=2;  
25. 
26.PL/SQL 过程已成功完成。  
27. 
28.SQL> select *from tt where id=:i;  
29. 
30.ID NAME  
31.---------- ----------------------------------------  
32.2 test  
33. 
34.SQL> print i;  
35. 
36.I  
37.----------  
38.2  
39. 
40.SQL> select sql_text,parse_calls from v$sql where sql_text like 'select * from t  
41.t where id=%';  
42. 
43.SQL_TEXT PARSE_CALLS  
44.------------------------------------------------------------ -----------  
45.select * from tt where id=2 1  
46.select * from tt where id=1 1  
47.select * from tt where id=:i 2  
48.SQL> 
SQL> select * from tt where id=1;

ID NAME
---------- ----------------------------------------
1 test

SQL> select * from tt where id=2;

ID NAME
---------- ----------------------------------------
2 test

SQL> variable i number;
SQL> exec :i :=1;

PL/SQL 过程已成功完成。

SQL> select *from tt where id=:i;

ID NAME
---------- ----------------------------------------
1 test

SQL> exec :i :=2;

PL/SQL 过程已成功完成。

SQL> select *from tt where id=:i;

ID NAME
---------- ----------------------------------------
2 test

SQL> print i;

I
----------
2

SQL> select sql_text,parse_calls from v$sql where sql_text like 'select * from t
t where id=%';

SQL_TEXT PARSE_CALLS
------------------------------------------------------------ -----------
select * from tt where id=2 1
select * from tt where id=1 1
select * from tt where id=:i 2
SQL>
从上面试验发现绑定变量i的使用使查询id=1和id=2的sqlselect *from tt where id=:i得以重复
使用,从而避免了hard parse,这里的PARSE_CALLS=2包括了一次soft parse

 


2.

前两天看到有人在pub上问在sqlplus中通过define和variable定义的变量的区别。其实define定义的我

理解不是变量而是字符常量,通过define定义之后,在通过&或者&&引用的时候不需要输入了,仅此而已。

oracle在执行的时候自动用值进行了替换;而variable定义的是绑定变量,上面已经提到。

view plaincopy to clipboardprint?
01.C:>sqlplus xys/manager  
02.SQL*Plus: Release 11.1.0.6.0 - Production on 星期二 4月 1 14:03:00 2008  
03.Copyright (c) 1982, 2007, Oracle. All rights reserved.  
04. 
05.连接到:  
06.Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production  
07.With the Partitioning, OLAP, Data Mining and Real Application Testing options  
08.SQL> define  
09.DEFINE _DATE = "01-4月 -08" (CHAR)  
10.DEFINE _CONNECT_IDENTIFIER = "db11" (CHAR)  
11.DEFINE _USER = "XYS" (CHAR)  
12.DEFINE _PRIVILEGE = "" (CHAR)  
13.DEFINE _SQLPLUS_RELEASE = "1101000600" (CHAR)  
14.DEFINE _EDITOR = "Notepad" (CHAR)  
15.DEFINE _O_VERSION = "Oracle Database 11g Enterprise Edition Release 11.1.0.  
16.6.0 - Production  
17.With the Partitioning, OLAP, Data Mining and Real Application Testing options" (  
18.CHAR)  
19.DEFINE _O_RELEASE = "1101000600" (CHAR)  
20.SQL> select *from tt;  
21.ID NAME  
22.---------- ----------  
23.1 a  
24.2 a  
25.3 "abc" 
26.SQL> define a  
27.SP2-0135: 符号 a 未定义  
28.SQL> define a=1  
29.SQL> define  
30.DEFINE _DATE = "01-4月 -08" (CHAR)  
31.DEFINE _CONNECT_IDENTIFIER = "db11" (CHAR)  
32.DEFINE _USER = "XYS" (CHAR)  
33.DEFINE _PRIVILEGE = "" (CHAR)  
34.DEFINE _SQLPLUS_RELEASE = "1101000600" (CHAR)  
35.DEFINE _EDITOR = "Notepad" (CHAR)  
36.DEFINE _O_VERSION = "Oracle Database 11g Enterprise Edition Release 11.1.0.  
37.6.0 - Production  
38.With the Partitioning, OLAP, Data Mining and Real Application Testing options" (CHAR)  
39.DEFINE _O_RELEASE = "1101000600" (CHAR)  
40.DEFINE A = "1" (CHAR)  
41.--通过上面显示define定义的应该是字符(串)常量。  
42.SQL> select * from tt where id=&a;  
43.原值 1: select * from tt where id=&a  
44.新值 1: select * from tt where id=1  
45.ID NAME  
46.---------- ----------  
47.1 a  
48.SQL> select * from tt where id=&&a;  
49.原值 1: select * from tt where id=&&a  
50.新值 1: select * from tt where id=1  
51.ID NAME  
52.---------- ----------  
53.1 a  
54.SQL> define b='a';  
55.SQL> define  
56.DEFINE _DATE = "01-4月 -08" (CHAR)  
57.DEFINE _CONNECT_IDENTIFIER = "db11" (CHAR)  
58.DEFINE _USER = "XYS" (CHAR)  
59.DEFINE _PRIVILEGE = "" (CHAR)  
60.DEFINE _SQLPLUS_RELEASE = "1101000600" (CHAR)  
61.DEFINE _EDITOR = "Notepad" (CHAR)  
62.DEFINE _O_VERSION = "Oracle Database 11g Enterprise Edition Release 11.1.0.  
63.6.0 - Production  
64.With the Partitioning, OLAP, Data Mining and Real Application Testing options" (  
65.CHAR)  
66.DEFINE _O_RELEASE = "1101000600" (CHAR)  
67.DEFINE A = "1" (CHAR)  
68.DEFINE B = "a" (CHAR)  
69. 
70.--如果是字符类型那么在引用时别忘了加上单引号,另外通过define定义之后在引用时不需要输入了。  
71.SQL> select * from tt where name=&&b;  
72.原值 1: select * from tt where name=&&b  
73.新值 1: select * from tt where name=a  
74.select * from tt where name=a  
75.*  
76.第 1 行出现错误:  
77.ORA-00904: "A": 标识符无效  
78. 
79.SQL> select * from tt where name='&&b';  
80.原值 1: select * from tt where name='&&b' 
81.新值 1: select * from tt where name='a' 
82.ID NAME  
83.---------- ----------  
84.1 a  
85.2 a  
86.SQL> select * from tt where name='&b';  
87.原值 1: select * from tt where name='&b' 
88.新值 1: select * from tt where name='a' 
89.ID NAME  
90.---------- ----------  
91.1 a  
92.2 a  
93.--执行sql时进行了替换  
94.SQL> select sql_text from v$sql where sql_text like 'select * from tt where name  
95.=%';  
96.SQL_TEXT  
97.--------------------------------------------------------------------------------  
98.select * from tt where name=1  
99.select * from tt where name='a' 
100.SQL> 
C:>sqlplus xys/manager
SQL*Plus: Release 11.1.0.6.0 - Production on 星期二 4月 1 14:03:00 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.

连接到:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> define
DEFINE _DATE = "01-4月 -08" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "db11" (CHAR)
DEFINE _USER = "XYS" (CHAR)
DEFINE _PRIVILEGE = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "1101000600" (CHAR)
DEFINE _EDITOR = "Notepad" (CHAR)
DEFINE _O_VERSION = "Oracle Database 11g Enterprise Edition Release 11.1.0.
6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options" (
CHAR)
DEFINE _O_RELEASE = "1101000600" (CHAR)
SQL> select *from tt;
ID NAME
---------- ----------
1 a
2 a
3 "abc"
SQL> define a
SP2-0135: 符号 a 未定义
SQL> define a=1
SQL> define
DEFINE _DATE = "01-4月 -08" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "db11" (CHAR)
DEFINE _USER = "XYS" (CHAR)
DEFINE _PRIVILEGE = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "1101000600" (CHAR)
DEFINE _EDITOR = "Notepad" (CHAR)
DEFINE _O_VERSION = "Oracle Database 11g Enterprise Edition Release 11.1.0.
6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options" (CHAR)
DEFINE _O_RELEASE = "1101000600" (CHAR)
DEFINE A = "1" (CHAR)
--通过上面显示define定义的应该是字符(串)常量。
SQL> select * from tt where id=&a;
原值 1: select * from tt where id=&a
新值 1: select * from tt where id=1
ID NAME
---------- ----------
1 a
SQL> select * from tt where id=&&a;
原值 1: select * from tt where id=&&a
新值 1: select * from tt where id=1
ID NAME
---------- ----------
1 a
SQL> define b='a';
SQL> define
DEFINE _DATE = "01-4月 -08" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "db11" (CHAR)
DEFINE _USER = "XYS" (CHAR)
DEFINE _PRIVILEGE = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "1101000600" (CHAR)
DEFINE _EDITOR = "Notepad" (CHAR)
DEFINE _O_VERSION = "Oracle Database 11g Enterprise Edition Release 11.1.0.
6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options" (
CHAR)
DEFINE _O_RELEASE = "1101000600" (CHAR)
DEFINE A = "1" (CHAR)
DEFINE B = "a" (CHAR)

--如果是字符类型那么在引用时别忘了加上单引号,另外通过define定义之后在引用时不需要输入了。
SQL> select * from tt where name=&&b;
原值 1: select * from tt where name=&&b
新值 1: select * from tt where name=a
select * from tt where name=a
*
第 1 行出现错误:
ORA-00904: "A": 标识符无效

SQL> select * from tt where name='&&b';
原值 1: select * from tt where name='&&b'
新值 1: select * from tt where name='a'
ID NAME
---------- ----------
1 a
2 a
SQL> select * from tt where name='&b';
原值 1: select * from tt where name='&b'
新值 1: select * from tt where name='a'
ID NAME
---------- ----------
1 a
2 a
--执行sql时进行了替换
SQL> select sql_text from v$sql where sql_text like 'select * from tt where name
=%';
SQL_TEXT
--------------------------------------------------------------------------------
select * from tt where name=1
select * from tt where name='a'
SQL>

 

3.

oracle在解析sql时会把plsql中定义的变量转为为绑定变量
view plaincopy to clipboardprint?
01.SQL> create table tt(id int , name varchar2(10));  
02. 
03.表已创建。  
04. 
05.SQL> alter session set sql_trace=true;  
06. 
07.会话已更改。  
08. 
09.SQL> declare  
10.2 begin  
11.3 for i in 1..100 loop  
12.4 insert into tt values(i,'test');  
13.5 end loop;  
14.6 commit;  
15.7 end;  
16.8 /  
17. 
18.PL/SQL 过程已成功完成。  
19. 
20.SQL> alter session set sql_trace=false;  
21.--trace file:  
22.=====================  
23.PARSING IN CURSOR #3 len=90 dep=0 uid=31 oct=47 lid=31 tim=7109565004 hv=962259239   
24. 
25.ad='668ec528' 
26.declare  
27.begin  
28.for i in 1..100 loop  
29.insert into tt values(i,'test');  
30.end loop;  
31.commit;  
32.end;  
33.END OF STMT  
34.PARSE #3:c=15625,e=5678,p=0,cr=3,cu=0,mis=1,r=0,dep=0,og=1,tim=7109564996  
35.=====================  
36.PARSING IN CURSOR #5 len=34 dep=1 uid=31 oct=2 lid=31 tim=7109565520 hv=1299226876   
37. 
38.ad='66869934' 
39.INSERT INTO TT VALUES(:B1 ,'test')  
40.END OF STMT  
41.PARSE #5:c=0,e=226,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=7109565513  
42.===================== 
SQL> create table tt(id int , name varchar2(10));

表已创建。

SQL> alter session set sql_trace=true;

会话已更改。

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

PL/SQL 过程已成功完成。

SQL> alter session set sql_trace=false;
--trace file:
=====================
PARSING IN CURSOR #3 len=90 dep=0 uid=31 oct=47 lid=31 tim=7109565004 hv=962259239

ad='668ec528'
declare
begin
for i in 1..100 loop
insert into tt values(i,'test');
end loop;
commit;
end;
END OF STMT
PARSE #3:c=15625,e=5678,p=0,cr=3,cu=0,mis=1,r=0,dep=0,og=1,tim=7109564996
=====================
PARSING IN CURSOR #5 len=34 dep=1 uid=31 oct=2 lid=31 tim=7109565520 hv=1299226876

ad='66869934'
INSERT INTO TT VALUES(:B1 ,'test')
END OF STMT
PARSE #5:c=0,e=226,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=7109565513
=====================
另外从hard parse的数据量上其实也可以大致猜测oracle会把plsql中定义的变量转换为绑定变量处理
view plaincopy to clipboardprint?
01.SQL> connect /as sysdba  
02.已连接。  
03.SQL> shutdown immediate  
04.数据库已经关闭。  
05.已经卸载数据库。  
06.ORACLE 例程已经关闭。  
07.SQL> startup  
08.ORACLE 例程已经启动。  
09. 
10.Total System Global Area 167772160 bytes  
11.Fixed Size 1247900 bytes  
12.Variable Size 67110244 bytes  
13.Database Buffers 96468992 bytes  
14.Redo Buffers 2945024 bytes  
15.数据库装载完毕。  
16.数据库已经打开。  
17.SQL> connect xys/manager  
18.已连接。  
19.SQL> drop table tt;  
20. 
21.表已删除。  
22. 
23.SQL> create table tt(id int , name varchar2(10));  
24. 
25.表已创建。  
26.SQL> col name format a30  
27.SQL> select a.*,b.name  
28.2 from v$sesstat a , v$statname b  
29.3 where a.statistic#=b.statistic#  
30.4 and a.sid=(select distinct sid from v$mystat)  
31.5 and b.name like '%parse%';  
32. 
33.SID STATISTIC# VALUE NAME  
34.---------- ---------- ---------- ------------------------------  
35.159 328 39 parse time cpu  
36.159 329 74 parse time elapsed  
37.159 330 339 parse count (total)  
38.159 331 165 parse count (hard)  
39.159 332 0 parse count (failures)  
40. 
41.SQL> declare  
42.2 begin  
43.3 for i in 1..100 loop  
44.4 insert into tt values(i,'test');  
45.5 end loop;  
46.6 commit;  
47.7 end;  
48.8 /  
49. 
50.PL/SQL 过程已成功完成。  
51. 
52.SQL> select a.*,b.name  
53.2 from v$sesstat a , v$statname b  
54.3 where a.statistic#=b.statistic#  
55.4 and a.sid=(select distinct sid from v$mystat)  
56.5 and b.name like '%parse%' 
57.6 /  
58. 
59.SID STATISTIC# VALUE NAME  
60.---------- ---------- ---------- ------------------------------  
61.159 328 39 parse time cpu  
62.159 329 74 parse time elapsed  
63.159 330 345 parse count (total)  
64.159 331 167 parse count (hard)  
65.159 332 0 parse count (failures)  
66. 
67.SQL> 
SQL> connect /as sysdba
已连接。
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area 167772160 bytes
Fixed Size 1247900 bytes
Variable Size 67110244 bytes
Database Buffers 96468992 bytes
Redo Buffers 2945024 bytes
数据库装载完毕。
数据库已经打开。
SQL> connect xys/manager
已连接。
SQL> drop table tt;

表已删除。

SQL> create table tt(id int , name varchar2(10));

表已创建。
SQL> col name format a30
SQL> select a.*,b.name
2 from v$sesstat a , v$statname b
3 where a.statistic#=b.statistic#
4 and a.sid=(select distinct sid from v$mystat)
5 and b.name like '%parse%';

SID STATISTIC# VALUE NAME
---------- ---------- ---------- ------------------------------
159 328 39 parse time cpu
159 329 74 parse time elapsed
159 330 339 parse count (total)
159 331 165 parse count (hard)
159 332 0 parse count (failures)

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

PL/SQL 过程已成功完成。

SQL> select a.*,b.name
2 from v$sesstat a , v$statname b
3 where a.statistic#=b.statistic#
4 and a.sid=(select distinct sid from v$mystat)
5 and b.name like '%parse%'
6 /

SID STATISTIC# VALUE NAME
---------- ---------- ---------- ------------------------------
159 328 39 parse time cpu
159 329 74 parse time elapsed
159 330 345 parse count (total)
159 331 167 parse count (hard)
159 332 0 parse count (failures)

SQL>
 

这里发现hard parse只增加了2,如果没有使用绑定变量的话,相信hard parse会更多

 

4.

过程中的参数会自动转化为绑定变量
view plaincopy to clipboardprint?
01.SQL> edit  
02.已写入 file afiedt.buf  
03. 
04.1 create or replace procedure proc_test(p_id int, p_name varchar2)  
05.2 is 
06.3 begin  
07.4 insert into tt values(p_id , p_name);  
08.5 commit;  
09.6* end;  
10.SQL> /  
11. 
12.过程已创建。  
13. 
14.SQL> alter session set sql_trace=true;  
15. 
16.会话已更改。  
17. 
18.SQL> exec proc_test(200,'test');  
19. 
20.PL/SQL 过程已成功完成。  
21. 
22.SQL> alter session set sql_trace=false;  
23. 
24.会话已更改。  
25.--trace file:  
26.alter session set sql_trace=true 
27.END OF STMT  
28.EXEC #3:c=0,e=749,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=7393908487  
29.=====================  
30.PARSING IN CURSOR #1 len=35 dep=0 uid=31 oct=47 lid=31 tim=7403000735 hv=526484776   
31. 
32.ad='6687b0b8' 
33.BEGIN proc_test(200,'test'); END;  
34.END OF STMT  
35.PARSE #1:c=0,e=2584,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=7403000727  
36.=====================  
37.PARSING IN CURSOR #6 len=33 dep=1 uid=31 oct=2 lid=31 tim=7403001293 hv=2874748229   
38. 
39.ad='668e9cd8' 
40.INSERT INTO TT VALUES(:B2 , :B1 )  
41.END OF STMT  
42.PARSE #6:c=0,e=246,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=7403001286  
43.===================== 
SQL> edit
已写入 file afiedt.buf

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

过程已创建。

SQL> alter session set sql_trace=true;

会话已更改。

SQL> exec proc_test(200,'test');

PL/SQL 过程已成功完成。

SQL> alter session set sql_trace=false;

会话已更改。
--trace file:
alter session set sql_trace=true
END OF STMT
EXEC #3:c=0,e=749,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=7393908487
=====================
PARSING IN CURSOR #1 len=35 dep=0 uid=31 oct=47 lid=31 tim=7403000735 hv=526484776

ad='6687b0b8'
BEGIN proc_test(200,'test'); END;
END OF STMT
PARSE #1:c=0,e=2584,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=7403000727
=====================
PARSING IN CURSOR #6 len=33 dep=1 uid=31 oct=2 lid=31 tim=7403001293 hv=2874748229

ad='668e9cd8'
INSERT INTO TT VALUES(:B2 , :B1 )
END OF STMT
PARSE #6:c=0,e=246,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=7403001286
=====================
 

另外也可以直观的观察:
view plaincopy to clipboardprint?
01.SQL> exec proc_test(200,'test');  
02. 
03.PL/SQL 过程已成功完成。  
04. 
05.SQL> select sql_text from v$sql where sql_text like '%proc_test%';  
06. 
07.SQL_TEXT  
08.--------------------------------------------------------------------------------  
09.BEGIN proc_test(200,'test'); END;  
10. 
11.SQL> 
SQL> exec proc_test(200,'test');

PL/SQL 过程已成功完成。

SQL> select sql_text from v$sql where sql_text like '%proc_test%';

SQL_TEXT
--------------------------------------------------------------------------------
BEGIN proc_test(200,'test'); END;

SQL>
 

在sqlplus里执行过程不能观察出来
下面在plsql developer执行一次过程之后再来看执行的情况
view plaincopy to clipboardprint?
01.SQL> select sql_text from v$sql where sql_text like '%proc_test%';  
02. 
03.SQL_TEXT  
04.--------------------------------------------------------------------------------  
05.begin -- Call the procedure proc_test(p_id =>:p_id, p_name =>:p_name); end;  
06. 
07.SQL> 
SQL> select sql_text from v$sql where sql_text like '%proc_test%';

SQL_TEXT
--------------------------------------------------------------------------------
begin -- Call the procedure proc_test(p_id =>:p_id, p_name =>:p_name); end;

SQL>
 

很显然oracle在执行过程时把参数转化为绑定变量了,其实从plsql developer中执行过程时的语法就能

看出来:
view plaincopy to clipboardprint?
01.begin  
02.-- Call the procedure  
03.proc_test(p_id => :p_id,  
04.p_name => :p_name);  
05.end; 
begin
-- Call the procedure
proc_test(p_id => :p_id,
p_name => :p_name);
end;
在输入参数列表框上面的执行语法就是这样的。

 

5.

在动态sql中使用绑定变量,动态sql中使用绑定变量非常明显也容易理解,下面给出2个简单的例子
view plaincopy to clipboardprint?
01.SQL> set serveroutput on  
02.SQL> declare  
03.   2   v_string varchar2(100);  
04.   3   v_id tt.id%type ;  
05.   4   v_name tt.name%type ;  
06.   5   begin  
07.   6   v_string:='select * from tt where id=:v_id';  
08.   7   execute immediate v_string into v_id , v_name using &a;  
09.   8   dbms_output.put_line(v_id||' '||v_name) ;  
10.   9   end;  
11.10   /  
12.输入 a 的值:   1  
13.原值 7: execute immediate v_string into v_id , v_name using &a;  
14.新值 7: execute immediate v_string into v_id , v_name using 1;  
15.1 test  
16. 
17.PL/SQL 过程已成功完成。  
18. 
19.SQL> declare  
20.   2   v_string varchar2(100);  
21.   3   v_id tt.id%type;  
22.   4   v_name tt.name%type ;  
23.   5   begin  
24.   6   v_string:='insert into tt values(:id,:name)';  
25.   7   execute immediate v_string using &id,&name ;  
26.   8   end;  
27.   9   /  
28.输入 id 的值:   1000  
29.输入 name 的值:   'test' 
30.原值 7: execute immediate v_string using &id,&name ;  
31.新值 7: execute immediate v_string using 1000,'test' ;  
32. 
33.PL/SQL 过程已成功完成。  
34. 
35.SQL> select * from tt where id=1000;  
36. 
37.       ID NAME  
38.---------- ----------  
39.   1000 test  
40. 
41.SQL> 
SQL> set serveroutput on
SQL> declare
   2   v_string varchar2(100);
   3   v_id tt.id%type ;
   4   v_name tt.name%type ;
   5   begin
   6   v_string:='select * from tt where id=:v_id';
   7   execute immediate v_string into v_id , v_name using &a;
   8   dbms_output.put_line(v_id||' '||v_name) ;
   9   end;
10   /
输入 a 的值:   1
原值 7: execute immediate v_string into v_id , v_name using &a;
新值 7: execute immediate v_string into v_id , v_name using 1;
1 test

PL/SQL 过程已成功完成。

SQL> declare
   2   v_string varchar2(100);
   3   v_id tt.id%type;
   4   v_name tt.name%type ;
   5   begin
   6   v_string:='insert into tt values(:id,:name)';
   7   execute immediate v_string using &id,&name ;
   8   end;
   9   /
输入 id 的值:   1000
输入 name 的值:   'test'
原值 7: execute immediate v_string using &id,&name ;
新值 7: execute immediate v_string using 1000,'test' ;

PL/SQL 过程已成功完成。

SQL> select * from tt where id=1000;

       ID NAME
---------- ----------
   1000 test

SQL>
 


=============================下面加上一些其他变量的使用方法=========================

 

eg001(&替换变量)

 

view plaincopy to clipboardprint?
01.SQL> select xh,xm from system.xs where zym='&zym';  
02.输入 zym 的值:  计算机  
03.原值    1: select xh,xm from system.xs where zym='&zym' 
04.新值    1: select xh,xm from system.xs where zym='计算机' 
05. 
06.XH     XM  
07.------ --------  
08.061101 王林  
09.061102 程明  
10.061103 王燕  
11.061104 韦严平  
12.061106 李方方  
13.061107 李明  
14.061108 林一帆  
15.061109 张强民  
16.061110 张蔚  
17.061111 赵琳  
18.061113 严红  
19. 
20.已选择11行。  
21. 
22.SQL> edit  
23.已写入 file afiedt.buf  
24. 
25.  1  select xh 学号,xm 姓名,avg(cj) as 平均成绩  
26.  2* from system.xs_xkb group by xh,xm  
27.SQL> /  
28. 
29.学号   姓名       平均成绩  
30.------ -------- ----------  
31.061103 王燕             71  
32.061210 李红庆           76  
33.061110 张蔚     91.3333333  
34.061220 吴薇华           82  
35.061104 韦严平   79.6666667  
36.061101 王林             78  
37.061204 马林林           91  
38.061106 李方方           72  
39.061218 孙研             70  
40.061102 程明             78  
41.061241 罗林琳           90  
42. 
43.学号   姓名       平均成绩  
44.------ -------- ----------  
45.061111 赵琳           80.5  
46.061109 张强民         76.5  
47.061216 孙祥欣           81  
48.061221 刘燕敏           79  
49. 
50.已选择15行。  
51. 
52.SQL> select * from system.xs_xkb where cj>=&cj; /*替换变量可以使用WHERE子句;ORDER BY子句;列表达式;表名;整个SELECT语句*/ 
53.输入 cj 的值:  90  
54.原值    1: select * from system.xs_xkb where cj>=&cj  
55.新值    1: select * from system.xs_xkb where cj>=90  
56. 
57.SQL> select xs.xh,&name,kcm,&column  
58.  2  from system.xs,&kc,system.xs_kc  
59.  3  where xs.xh=xs_kc.xh and &condition  
60.  4  and kcm=&kcm  
61.  5  order by & column;  
62.输入 name 的值:  xm  
63.输入 column 的值:  cj  
64.原值    1: select xs.xh,&name,kcm,&column  
65.新值    1: select xs.xh,xm,kcm,cj  
66.输入 kc 的值:  system.kc  
67.原值    2: from system.xs,&kc,system.xs_kc  
68.新值    2: from system.xs,system.kc,system.xs_kc  
69.输入 condition 的值:  kc.kch=xs_kc.kch  
70.原值    3: where xs.xh=xs_kc.xh and &condition  
71.新值    3: where xs.xh=xs_kc.xh and kc.kch=xs_kc.kch  
72.输入 kcm 的值:  '离散数学' 
73.原值    4: and kcm=&kcm  
74.新值    4: and kcm='离散数学' 
75.输入 column 的值:  cj  
76.原值    5: order by & column  
77.新值    5: order by cj  
78. 
79.XH     XM       KCM                      CJ  
80.------ -------- ---------------- ----------  
81.061104 韦严平   离散数学                 65  
82.061109 张强民   离散数学                 70  
83.061101 王林     离散数学                 76  
84.061102 程明     离散数学                 78  
85.061106 李方方   离散数学                 80  
86.061103 王燕     离散数学                 81  
87.061110 张蔚     离散数学                 89 
SQL> select xh,xm from system.xs where zym='&zym';
输入 zym 的值:  计算机
原值    1: select xh,xm from system.xs where zym='&zym'
新值    1: select xh,xm from system.xs where zym='计算机'

XH     XM
------ --------
061101 王林
061102 程明
061103 王燕
061104 韦严平
061106 李方方
061107 李明
061108 林一帆
061109 张强民
061110 张蔚
061111 赵琳
061113 严红

已选择11行。

SQL> edit
已写入 file afiedt.buf

  1  select xh 学号,xm 姓名,avg(cj) as 平均成绩
  2* from system.xs_xkb group by xh,xm
SQL> /

学号   姓名       平均成绩
------ -------- ----------
061103 王燕             71
061210 李红庆           76
061110 张蔚     91.3333333
061220 吴薇华           82
061104 韦严平   79.6666667
061101 王林             78
061204 马林林           91
061106 李方方           72
061218 孙研             70
061102 程明             78
061241 罗林琳           90

学号   姓名       平均成绩
------ -------- ----------
061111 赵琳           80.5
061109 张强民         76.5
061216 孙祥欣           81
061221 刘燕敏           79

已选择15行。

SQL> select * from system.xs_xkb where cj>=&cj; /*替换变量可以使用WHERE子句;ORDER BY子句;列表达式;表名;整个SELECT语句*/
输入 cj 的值:  90
原值    1: select * from system.xs_xkb where cj>=&cj
新值    1: select * from system.xs_xkb where cj>=90

SQL> select xs.xh,&name,kcm,&column
  2  from system.xs,&kc,system.xs_kc
  3  where xs.xh=xs_kc.xh and &condition
  4  and kcm=&kcm
  5  order by & column;
输入 name 的值:  xm
输入 column 的值:  cj
原值    1: select xs.xh,&name,kcm,&column
新值    1: select xs.xh,xm,kcm,cj
输入 kc 的值:  system.kc
原值    2: from system.xs,&kc,system.xs_kc
新值    2: from system.xs,system.kc,system.xs_kc
输入 condition 的值:  kc.kch=xs_kc.kch
原值    3: where xs.xh=xs_kc.xh and &condition
新值    3: where xs.xh=xs_kc.xh and kc.kch=xs_kc.kch
输入 kcm 的值:  '离散数学'
原值    4: and kcm=&kcm
新值    4: and kcm='离散数学'
输入 column 的值:  cj
原值    5: order by & column
新值    5: order by cj

XH     XM       KCM                      CJ
------ -------- ---------------- ----------
061104 韦严平   离散数学                 65
061109 张强民   离散数学                 70
061101 王林     离散数学                 76
061102 程明     离散数学                 78
061106 李方方   离散数学                 80
061103 王燕     离散数学                 81
061110 张蔚     离散数学                 89

 


eg002(&&替换变量)

 

view plaincopy to clipboardprint?
01.--&&替换变量系统一直用同一个值处理,清除用undefine 变量名清除  
02.SQL> edit  
03.已写入 file afiedt.buf  
04. 
05.  1  select xs.xh,&name,kcm,&&column   /*清除替换变量(undefine column)*/ 
06.  2  from system.xs,&kc,system.xs_kc  
07.  3  where xs.xh=xs_kc.xh and &condition  
08.  4  and kcm=&kcm  
09.  5* order by &column  
10.SQL> /  
11.输入 name 的值:  xm  
12.输入 column 的值:  cj  
13.原值    1: select xs.xh,&name,kcm,&&column  
14.新值    1: select xs.xh,xm,kcm,cj  
15.输入 kc 的值:  system.kc  
16.原值    2: from system.xs,&kc,system.xs_kc  
17.新值    2: from system.xs,system.kc,system.xs_kc  
18.输入 condition 的值:  kc.kch=xs_kc.kch  
19.原值    3: where xs.xh=xs_kc.xh and &condition  
20.新值    3: where xs.xh=xs_kc.xh and kc.kch=xs_kc.kch  
21.输入 kcm 的值:  '离散数学' 
22.原值    4: and kcm=&kcm  
23.新值    4: and kcm='离散数学' 
24.原值    5: order by &column             /*使用&&替换变量的好处,相同变量只输第一次就OK*/ 
25.新值    5: order by cj  
26. 
27.XH     XM       KCM                      CJ  
28.------ -------- ---------------- ----------  
29.061104 韦严平   离散数学                 65  
30.061109 张强民   离散数学                 70  
31.061101 王林     离散数学                 76  
32.061102 程明     离散数学                 78  
33.061106 李方方   离散数学                 80  
34.061103 王燕     离散数学                 81  
35.061110 张蔚     离散数学                 89  
36. 
37.已选择7行。 
--&&替换变量系统一直用同一个值处理,清除用undefine 变量名清除
SQL> edit
已写入 file afiedt.buf

  1  select xs.xh,&name,kcm,&&column   /*清除替换变量(undefine column)*/
  2  from system.xs,&kc,system.xs_kc
  3  where xs.xh=xs_kc.xh and &condition
  4  and kcm=&kcm
  5* order by &column
SQL> /
输入 name 的值:  xm
输入 column 的值:  cj
原值    1: select xs.xh,&name,kcm,&&column
新值    1: select xs.xh,xm,kcm,cj
输入 kc 的值:  system.kc
原值    2: from system.xs,&kc,system.xs_kc
新值    2: from system.xs,system.kc,system.xs_kc
输入 condition 的值:  kc.kch=xs_kc.kch
原值    3: where xs.xh=xs_kc.xh and &condition
新值    3: where xs.xh=xs_kc.xh and kc.kch=xs_kc.kch
输入 kcm 的值:  '离散数学'
原值    4: and kcm=&kcm
新值    4: and kcm='离散数学'
原值    5: order by &column             /*使用&&替换变量的好处,相同变量只输第一次就OK*/
新值    5: order by cj

XH     XM       KCM                      CJ
------ -------- ---------------- ----------
061104 韦严平   离散数学                 65
061109 张强民   离散数学                 70
061101 王林     离散数学                 76
061102 程明     离散数学                 78
061106 李方方   离散数学                 80
061103 王燕     离散数学                 81
061110 张蔚     离散数学                 89

已选择7行。

 
eg003

DEFINE[variable[=value]]
UNDEFINE清除定义的变量

view plaincopy to clipboardprint?
01.SQL> define specialty=通信工程  
02.SQL> define specialty  
03.DEFINE SPECIALTY       = "通信工程" (CHAR)  
04.SQL> select xh,xm,xb,cssj,zxf from system.xs  
05.  2  where zym='&specialty';  
06. 
07.XH     XM       XB CSSJ                  ZXF  
08.------ -------- -- -------------- ----------  
09.061202 王林     男 29-10月-85             40  
10.061210 李红庆   女 01-5月 -85             44  
11.061201 王敏     男 10-6月 -84             42  
12.061203 王玉民   男 26-3月 -86             42  
13.061204 马林林   女 10-2月 -84             42  
14.061206 李计     女 20-9月 -85             42  
15.061216 孙祥欣   女 09-3月 -84             42  
16.061218 孙研     男 09-10月-86             42  
17.061220 吴薇华   女 18-3月 -86             42  
18.061221 刘燕敏   女 12-11月-85             42  
19.061241 罗林琳   女 30-1月 -86             50  
20. 
21.已选择11行。 
SQL> define specialty=通信工程
SQL> define specialty
DEFINE SPECIALTY       = "通信工程" (CHAR)
SQL> select xh,xm,xb,cssj,zxf from system.xs
  2  where zym='&specialty';

XH     XM       XB CSSJ                  ZXF
------ -------- -- -------------- ----------
061202 王林     男 29-10月-85             40
061210 李红庆   女 01-5月 -85             44
061201 王敏     男 10-6月 -84             42
061203 王玉民   男 26-3月 -86             42
061204 马林林   女 10-2月 -84             42
061206 李计     女 20-9月 -85             42
061216 孙祥欣   女 09-3月 -84             42
061218 孙研     男 09-10月-86             42
061220 吴薇华   女 18-3月 -86             42
061221 刘燕敏   女 12-11月-85             42
061241 罗林琳   女 30-1月 -86             50

已选择11行。

 


eg004
ACCEPT variable[datatype[NUMBER|CHAR|DATE]][FORMAT format][PROMPT text][HIDE]/*variable:指定接收值的变量。该名称的变量不存在,那么SQL重建该变量;datatype:变量数据类型,默认为CHAR*/


view plaincopy to clipboardprint?
01.SQL> accept num prompt'请输入课程号:' 
02.请输入课程号:101  
03.SQL> set verify on  
04.SQL>   
05.  1  select xh,kcm,cj from system.xs_kc,system.kc  
06.  2  where xs_kc.kch=kc.kch and kc.kch='&num' 
07.  3* order by cj  
08.SQL> /  
09.原值    2: where xs_kc.kch=kc.kch and kc.kch='&num' 
10.新值    2: where xs_kc.kch=kc.kch and kc.kch='101' 
11. 
12.XH     KCM                      CJ  
13.------ ---------------- ----------  
14.061103 计算机基础               62  
15.061106 计算机基础               65  
16.061218 计算机基础               70  
17.061210 计算机基础               76  
18.061221 计算机基础               79  
19.061101 计算机基础               80  
20.061216 计算机基础               81  
21.061220 计算机基础               82  
22.061241 计算机基础               90  
23.061104 计算机基础               90  
24.061111 计算机基础               91  
25. 
26.XH     KCM                      CJ  
27.------ ---------------- ----------  
28.061204 计算机基础               91  
29.061110 计算机基础               95  
30. 
31.已选择13行。  
32. 
33.SQL>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值