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

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

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

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

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

1.

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

  1. SQL> select * from tt where id=1;
  2. ID NAME
  3. ---------- ----------------------------------------
  4. 1 test
  5. SQL> select * from tt where id=2;
  6. ID NAME
  7. ---------- ----------------------------------------
  8. 2 test
  9. SQL> variable i number;
  10. SQL> exec :i :=1;
  11. PL/SQL 过程已成功完成。
  12. SQL> select *from tt where id=:i;
  13. ID NAME
  14. ---------- ----------------------------------------
  15. 1 test
  16. SQL> exec :i :=2;
  17. PL/SQL 过程已成功完成。
  18. SQL> select *from tt where id=:i;
  19. ID NAME
  20. ---------- ----------------------------------------
  21. 2 test
  22. SQL> print i;
  23. I
  24. ----------
  25. 2
  26. SQL> select sql_text,parse_calls from v$sql where sql_text like 'select * from t
  27. t where id=%';
  28. SQL_TEXT PARSE_CALLS
  29. ------------------------------------------------------------ -----------
  30. select * from tt where id=2 1
  31. select * from tt where id=1 1
  32. select * from tt where id=:i 2
  33. 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定义的是绑定变量,上面已经提到。

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

  1. SQL> create table tt(id int , name varchar2(10));
  2. 表已创建。
  3. SQL> alter session set sql_trace=true;
  4. 会话已更改。
  5. SQL> declare
  6. 2 begin
  7. 3 for i in 1..100 loop
  8. 4 insert into tt values(i,'test');
  9. 5 end loop;
  10. 6 commit;
  11. 7 end;
  12. 8 /
  13. PL/SQL 过程已成功完成。
  14. SQL> alter session set sql_trace=false;
  15. --trace file:
  16. =====================
  17. PARSING IN CURSOR #3 len=90 dep=0 uid=31 oct=47 lid=31 tim=7109565004 hv=962259239
  18. ad='668ec528'
  19. declare
  20. begin
  21. for i in 1..100 loop
  22. insert into tt values(i,'test');
  23. end loop;
  24. commit;
  25. end;
  26. END OF STMT
  27. PARSE #3:c=15625,e=5678,p=0,cr=3,cu=0,mis=1,r=0,dep=0,og=1,tim=7109564996
  28. =====================
  29. PARSING IN CURSOR #5 len=34 dep=1 uid=31 oct=2 lid=31 tim=7109565520 hv=1299226876
  30. ad='66869934'
  31. INSERT INTO TT VALUES(:B1 ,'test')
  32. END OF STMT
  33. PARSE #5:c=0,e=226,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=7109565513
  34. =====================

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中定义的变量转换为绑定变量处理

  1. SQL> connect /as sysdba
  2. 已连接。
  3. SQL> shutdown immediate
  4. 数据库已经关闭。
  5. 已经卸载数据库。
  6. ORACLE 例程已经关闭。
  7. SQL> startup
  8. ORACLE 例程已经启动。
  9. Total System Global Area 167772160 bytes
  10. Fixed Size 1247900 bytes
  11. Variable Size 67110244 bytes
  12. Database Buffers 96468992 bytes
  13. Redo Buffers 2945024 bytes
  14. 数据库装载完毕。
  15. 数据库已经打开。
  16. SQL> connect xys/manager
  17. 已连接。
  18. SQL> drop table tt;
  19. 表已删除。
  20. SQL> create table tt(id int , name varchar2(10));
  21. 表已创建。
  22. SQL> col name format a30
  23. SQL> select a.*,b.name
  24. 2 from v$sesstat a , v$statname b
  25. 3 where a.statistic#=b.statistic#
  26. 4 and a.sid=(select distinct sid from v$mystat)
  27. 5 and b.name like '%parse%';
  28. SID STATISTIC# VALUE NAME
  29. ---------- ---------- ---------- ------------------------------
  30. 159 328 39 parse time cpu
  31. 159 329 74 parse time elapsed
  32. 159 330 339 parse count (total)
  33. 159 331 165 parse count (hard)
  34. 159 332 0 parse count (failures)
  35. SQL> declare
  36. 2 begin
  37. 3 for i in 1..100 loop
  38. 4 insert into tt values(i,'test');
  39. 5 end loop;
  40. 6 commit;
  41. 7 end;
  42. 8 /
  43. PL/SQL 过程已成功完成。
  44. SQL> select a.*,b.name
  45. 2 from v$sesstat a , v$statname b
  46. 3 where a.statistic#=b.statistic#
  47. 4 and a.sid=(select distinct sid from v$mystat)
  48. 5 and b.name like '%parse%'
  49. 6 /
  50. SID STATISTIC# VALUE NAME
  51. ---------- ---------- ---------- ------------------------------
  52. 159 328 39 parse time cpu
  53. 159 329 74 parse time elapsed
  54. 159 330 345 parse count (total)
  55. 159 331 167 parse count (hard)
  56. 159 332 0 parse count (failures)
  57. 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.

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

  1. SQL> edit
  2. 已写入 file afiedt.buf
  3. 1 create or replace procedure proc_test(p_id int, p_name varchar2)
  4. 2 is
  5. 3 begin
  6. 4 insert into tt values(p_id , p_name);
  7. 5 commit;
  8. 6* end;
  9. SQL> /
  10. 过程已创建。
  11. SQL> alter session set sql_trace=true;
  12. 会话已更改。
  13. SQL> exec proc_test(200,'test');
  14. PL/SQL 过程已成功完成。
  15. SQL> alter session set sql_trace=false;
  16. 会话已更改。
  17. --trace file:
  18. alter session set sql_trace=true
  19. END OF STMT
  20. EXEC #3:c=0,e=749,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=7393908487
  21. =====================
  22. PARSING IN CURSOR #1 len=35 dep=0 uid=31 oct=47 lid=31 tim=7403000735 hv=526484776
  23. ad='6687b0b8'
  24. BEGIN proc_test(200,'test'); END;
  25. END OF STMT
  26. PARSE #1:c=0,e=2584,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=7403000727
  27. =====================
  28. PARSING IN CURSOR #6 len=33 dep=1 uid=31 oct=2 lid=31 tim=7403001293 hv=2874748229
  29. ad='668e9cd8'
  30. INSERT INTO TT VALUES(:B2 , :B1 )
  31. END OF STMT
  32. PARSE #6:c=0,e=246,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=7403001286
  33. =====================

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
=====================

另外也可以直观的观察:

  1. SQL> exec proc_test(200,'test');
  2. PL/SQL 过程已成功完成。
  3. SQL> select sql_text from v$sql where sql_text like '%proc_test%';
  4. SQL_TEXT
  5. --------------------------------------------------------------------------------
  6. BEGIN proc_test(200,'test'); END;
  7. 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执行一次过程之后再来看执行的情况

  1. SQL> select sql_text from v$sql where sql_text like '%proc_test%';
  2. SQL_TEXT
  3. --------------------------------------------------------------------------------
  4. begin -- Call the procedure proc_test(p_id =>:p_id, p_name =>:p_name); end;
  5. 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中执行过程时的语法就能

看出来:

  1. begin
  2. -- Call the procedure
  3. proc_test(p_id => :p_id,
  4. p_name => :p_name);
  5. end;

begin
-- Call the procedure
proc_test(p_id => :p_id,
p_name => :p_name);
end;
在输入参数列表框上面的执行语法就是这样的。

5.

在动态sql中使用绑定变量,动态sql中使用绑定变量非常明显也容易理解,下面给出2个简单的例子

  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;
  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. PL/SQL 过程已成功完成。
  17. SQL> declare
  18. 2   v_string varchar2(100);
  19. 3   v_id tt.id%type;
  20. 4   v_name tt.name%type ;
  21. 5   begin
  22. 6   v_string:='insert into tt values(:id,:name)';
  23. 7   execute immediate v_string using &id,&name ;
  24. 8   end;
  25. 9   /
  26. 输入 id 的值:   1000
  27. 输入 name 的值:   'test'
  28. 原值 7: execute immediate v_string using &id,&name ;
  29. 新值 7: execute immediate v_string using 1000,'test' ;
  30. PL/SQL 过程已成功完成。
  31. SQL> select * from tt where id=1000;
  32. ID NAME
  33. ---------- ----------
  34. 1000 test
  35. 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(&替换变量)

  1. SQL> select xh,xm from system.xs where zym='&zym';
  2. 输入 zym 的值:  计算机
  3. 原值    1: select xh,xm from system.xs where zym='&zym'
  4. 新值    1: select xh,xm from system.xs where zym='计算机'
  5. XH     XM
  6. ------ --------
  7. 061101 王林
  8. 061102 程明
  9. 061103 王燕
  10. 061104 韦严平
  11. 061106 李方方
  12. 061107 李明
  13. 061108 林一帆
  14. 061109 张强民
  15. 061110 张蔚
  16. 061111 赵琳
  17. 061113 严红
  18. 已选择11行。
  19. SQL> edit
  20. 已写入 file afiedt.buf
  21. 1  select xh 学号,xm 姓名,avg(cj) as 平均成绩
  22. 2* from system.xs_xkb group by xh,xm
  23. SQL> /
  24. 学号   姓名       平均成绩
  25. ------ -------- ----------
  26. 061103 王燕             71
  27. 061210 李红庆           76
  28. 061110 张蔚     91.3333333
  29. 061220 吴薇华           82
  30. 061104 韦严平   79.6666667
  31. 061101 王林             78
  32. 061204 马林林           91
  33. 061106 李方方           72
  34. 061218 孙研             70
  35. 061102 程明             78
  36. 061241 罗林琳           90
  37. 学号   姓名       平均成绩
  38. ------ -------- ----------
  39. 061111 赵琳           80.5
  40. 061109 张强民         76.5
  41. 061216 孙祥欣           81
  42. 061221 刘燕敏           79
  43. 已选择15行。
  44. SQL> select * from system.xs_xkb where cj>=&cj; /*替换变量可以使用WHERE子句;ORDER BY子句;列表达式;表名;整个SELECT语句*/
  45. 输入 cj 的值:  90
  46. 原值    1: select * from system.xs_xkb where cj>=&cj
  47. 新值    1: select * from system.xs_xkb where cj>=90
  48. SQL> select xs.xh,&name,kcm,&column
  49. 2  from system.xs,&kc,system.xs_kc
  50. 3  where xs.xh=xs_kc.xh and &condition
  51. 4  and kcm=&kcm
  52. 5  order by & column;
  53. 输入 name 的值:  xm
  54. 输入 column 的值:  cj
  55. 原值    1: select xs.xh,&name,kcm,&column
  56. 新值    1: select xs.xh,xm,kcm,cj
  57. 输入 kc 的值:  system.kc
  58. 原值    2: from system.xs,&kc,system.xs_kc
  59. 新值    2: from system.xs,system.kc,system.xs_kc
  60. 输入 condition 的值:  kc.kch=xs_kc.kch
  61. 原值    3: where xs.xh=xs_kc.xh and &condition
  62. 新值    3: where xs.xh=xs_kc.xh and kc.kch=xs_kc.kch
  63. 输入 kcm 的值:  '离散数学'
  64. 原值    4: and kcm=&kcm
  65. 新值    4: and kcm='离散数学'
  66. 输入 column 的值:  cj
  67. 原值    5: order by & column
  68. 新值    5: order by cj
  69. XH     XM       KCM                      CJ
  70. ------ -------- ---------------- ----------
  71. 061104 韦严平   离散数学                 65
  72. 061109 张强民   离散数学                 70
  73. 061101 王林     离散数学                 76
  74. 061102 程明     离散数学                 78
  75. 061106 李方方   离散数学                 80
  76. 061103 王燕     离散数学                 81
  77. 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(&&替换变量)

  1. --&&替换变量系统一直用同一个值处理,清除用undefine 变量名清除
  2. SQL> edit
  3. 已写入 file afiedt.buf
  4. 1  select xs.xh,&name,kcm,&&column   /*清除替换变量(undefine column)*/
  5. 2  from system.xs,&kc,system.xs_kc
  6. 3  where xs.xh=xs_kc.xh and &condition
  7. 4  and kcm=&kcm
  8. 5* order by &column
  9. SQL> /
  10. 输入 name 的值:  xm
  11. 输入 column 的值:  cj
  12. 原值    1: select xs.xh,&name,kcm,&&column
  13. 新值    1: select xs.xh,xm,kcm,cj
  14. 输入 kc 的值:  system.kc
  15. 原值    2: from system.xs,&kc,system.xs_kc
  16. 新值    2: from system.xs,system.kc,system.xs_kc
  17. 输入 condition 的值:  kc.kch=xs_kc.kch
  18. 原值    3: where xs.xh=xs_kc.xh and &condition
  19. 新值    3: where xs.xh=xs_kc.xh and kc.kch=xs_kc.kch
  20. 输入 kcm 的值:  '离散数学'
  21. 原值    4: and kcm=&kcm
  22. 新值    4: and kcm='离散数学'
  23. 原值    5: order by &column             /*使用&&替换变量的好处,相同变量只输第一次就OK*/
  24. 新值    5: order by cj
  25. XH     XM       KCM                      CJ
  26. ------ -------- ---------------- ----------
  27. 061104 韦严平   离散数学                 65
  28. 061109 张强民   离散数学                 70
  29. 061101 王林     离散数学                 76
  30. 061102 程明     离散数学                 78
  31. 061106 李方方   离散数学                 80
  32. 061103 王燕     离散数学                 81
  33. 061110 张蔚     离散数学                 89
  34. 已选择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清除定义的变量

  1. SQL> define specialty=通信工程
  2. SQL> define specialty
  3. DEFINE SPECIALTY       = "通信工程" (CHAR)
  4. SQL> select xh,xm,xb,cssj,zxf from system.xs
  5. 2  where zym='&specialty';
  6. XH     XM       XB CSSJ                  ZXF
  7. ------ -------- -- -------------- ----------
  8. 061202 王林     男 29-10月-85             40
  9. 061210 李红庆   女 01-5月 -85             44
  10. 061201 王敏     男 10-6月 -84             42
  11. 061203 王玉民   男 26-3月 -86             42
  12. 061204 马林林   女 10-2月 -84             42
  13. 061206 李计     女 20-9月 -85             42
  14. 061216 孙祥欣   女 09-3月 -84             42
  15. 061218 孙研     男 09-10月-86             42
  16. 061220 吴薇华   女 18-3月 -86             42
  17. 061221 刘燕敏   女 12-11月-85             42
  18. 061241 罗林琳   女 30-1月 -86             50
  19. 已选择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*/

  1. SQL> accept num prompt'请输入课程号:'
  2. 请输入课程号:101
  3. SQL> set verify on
  4. SQL>
  5. 1  select xh,kcm,cj from system.xs_kc,system.kc
  6. 2  where xs_kc.kch=kc.kch and kc.kch='&num'
  7. 3* order by cj
  8. SQL> /
  9. 原值    2: where xs_kc.kch=kc.kch and kc.kch='&num'
  10. 新值    2: where xs_kc.kch=kc.kch and kc.kch='101'
  11. XH     KCM                      CJ
  12. ------ ---------------- ----------
  13. 061103 计算机基础               62
  14. 061106 计算机基础               65
  15. 061218 计算机基础               70
  16. 061210 计算机基础               76
  17. 061221 计算机基础               79
  18. 061101 计算机基础               80
  19. 061216 计算机基础               81
  20. 061220 计算机基础               82
  21. 061241 计算机基础               90
  22. 061104 计算机基础               90
  23. 061111 计算机基础               91
  24. XH     KCM                      CJ
  25. ------ ---------------- ----------
  26. 061204 计算机基础               91
  27. 061110 计算机基础               95
  28. 已选择13行。
  29. SQL>

ORACLE 绑定变量用法总结 .的更多相关文章

  1. [转]ORACLE 绑定变量用法总结

    转:http://blog.csdn.net/wanghai__/article/details/4778343 在oracle 中,对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析 ...

  2. SQL优化 | Oracle 绑定变量

    之前整理过一篇有关绑定变量的文章,不太详细,重新补充一下. Oracle 绑定变量 http://www.cndba.cn/Dave/article/1275 一.绑定变量 bind variable ...

  3. Oracle SQL调优之绑定变量用法简介

    目录 一.SQL执行过程简介 二.绑定变量典型用法 2.1.在SQL中绑定变量 2.2.在PL/SQL中使用绑定变量 2.3.PL/SQL批量绑定变量 2.4.Java代码里使用绑定变量 最近在看&l ...

  4. Oracle绑定变量

    select * from table where id = ? 类似于上面这样的sql,如果不用绑定变量,每次执行时Oracle会认为是不同的sql,会在每次执行时生成一遍执行计划,而执行计划的生成 ...

  5. oracle 绑定变量

    “绑定变量”这个词也许对于某些人来说看以来陌生,其实我们在很早的时候就已经开始运用它了. 在java中使用的PrepareStatement对象,大家一定会说这不是将sql语句做预编译操作嘛,被封装的 ...

  6. Oracle绑定变量优缺点

    参考:http://f.dataguru.cn/thread-208881-1-1.html 参考:http://blog.sina.com.cn/s/blog_4d9ece9a0100caw8.ht ...

  7. Oracle绑定变量在C#.NET中的应用及意义

    一. 什么是绑定变量 绑定变量(bind variable) : select * from emp where empno=:empno; 是用户放入查询中的占位符,它会告诉Oracle“我会随后为 ...

  8. oracle绑定变量测试及性能对比

    1.创建测试数据 2.查看cursor_sharing的值 SQL> show parameter cursor_sharing; NAME TYPE VALUE --------------- ...

  9. ORACLE绑定变量隐式转换导致性能问题

    年后一次系统升级后,监控数据库的工具DPA发现数据库的Total Wait时间突然飙增,如下截图所示,数据库的总体等待时间对比升级前飙增了非常多 另外就是发现出现了较多的等待事件,主要有latch: ...

随机推荐

  1. VM11里安装ubuntukylin-16.04-desktop-amd64遇到问题

    一.ubuntu linux的地址 http://www.ubuntu-china.cn/ 这个地址是中国站,点击下载菜单后,有两个版本,一个是ubuntu,一个是kylin.后者是专门加了中文程序的 ...

  2. java多线程什么时候释放锁—wait()、notify()

    由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不需要锁的时候及时释放锁是很重要的.在以下情况下,持有锁的线程会释放锁:    1. 执行完同步代码块.    2. 在执行 ...

  3. Centos下搭建 nginx+uwsgi+python

    python做web应用最麻烦的还是配置服务器了,此话不假,光中间件就有好几种选择,fastcgi.wsgi.uwsgi,难 免让人眼花缭乱. 而听说uwsgi的效率是fastcgi和wsgi的10倍 ...

  4. [TYVJ] P1006 ISBN

    ISBN 背景 Background NOIP2008年普及组第一题   描述 Description    每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1位识别码和3位 ...

  5. text-overflow 文字溢出时的设置

    text-overflow : clip | ellipsis clip: 不显示省略标记(...),而是简单的裁切. ellipsis: 当对象内文本溢出时显示省略标记(...) 设置或检索是否使用 ...

  6. 关于css浮动的一些总结

    首先给浮动一个定义吧 浮动可以理解为让某个div元素脱离标准流,漂浮在标准流之上,和标准流不是一个层次. 从测试中来看 元素之间的浮动关系是根据上一个元素来判断的如果上一个元素是浮动的它会跟在浮动元素 ...

  7. QML的渲染方式相较于之前的版本也有了重大的更新(CPU线程负责绘制,GPU线程负责渲染),还有好多经常评论 good

    作者:qyvlik链接:http://www.zhihu.com/question/38867614/answer/78583440来源:知乎著作权归作者所有,转载请联系作者获得授权. 做UI啊.如果 ...

  8. nc命令总结

    1.远程拷贝文件从server1拷贝文件到server2上.需要先在server2上,用nc激活监听,server2上运行: 引用 [root@hatest2 tmp]# nc -l 1234 > ...

  9. 嵌入式设备web服务器

    操作系统:ubuntu10.04 前言:    为了提高对设备的易操作性,很多设备中提供pc机直接通过浏览器操作设备的功能.这就需要在设备中实现web服务器.    现在在嵌入式设备中所使用的web服 ...

  10. [转]UltraISO制作U盘启动盘安装Win7/9/10系统攻略

    原文地址:http://www.cnblogs.com/pchmonster/p/4716708.html U盘安装好处就是不用使用笨拙的光盘,光盘还容易出现问题,无法读取的问题.U盘体积小,携带方便 ...