--定义变量
SQL> var a number;

--给绑定变量赋值
SQL> exec :a :=123;

PL/SQL procedure successfully completed.

--使用该绑定变量
SQL> select * from test where n1= :a;

N1
----------
       123

Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020     --记住 执行计划的id

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     5 |    69   (2)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |     1 |     5 |    69   (2)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("N1"=TO_NUMBER(:A))

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        191  consistent gets
          0  physical reads
          0  redo size
        521  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

--再次给绑定变量赋值
SQL> exec :a :=1234;

PL/SQL procedure successfully completed.

--使用该绑定变量
SQL> select * from test where n1= :a;

N1
----------
      1234

Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020   传给绑定变量的值 变了,但是依然采用原先的执行计划

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     5 |    69   (2)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |     1 |     5 |    69   (2)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("N1"=TO_NUMBER(:A))

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        191  consistent gets
          0  physical reads
          0  redo size
        521  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
----------------------------------------------------------------------------------------------------------

在ORACLE中,使用绑定变量,可以降低硬解析,通常可以提高系统的性能(注意,是通常,不是任何情况下)。

以表tabletest为例,我们来看看如何使用绑定变量,tabletest的表结构为

Create table tabletest(

field1 number(10),

field2 number(10),

field3 number(10),

field4 number(10),

field5 number(10));

绑定变量可以理解为一个占位符 ,例如:

declare

i number;

j number;

sqlstr varchar2(200);

begin

i:=1;

j:=2;

sqlstr:='insert into tabletest (field1,field2,field3,field4,field5)    values(:x,:x,:y,:x,:x)';
      execute immediate sqlstr using i,i,j,i,i;

end;

这样的一段代码中,使用i,i,j,i,i来对应:x,:x,:y,:x,:x。这段代码是正确的,但如果以为sqlstr中只有:x,:y这两个绑定变量,而把语句execute immediate sqlstr using i,i,j,i,i; 改为execute immediate sqlstr using i,j; 就会在运行中出现绑定变量数量不够的错误。

上面的正确代码执行完后,插入的记录从field1到field5的数据应该是1,1,2,1,1。

如果我们把execute
immediate sqlstr using i,i,j,i,i; 改成execute immediate sqlstr using i,j,j,i,i; 执行之后,察看插入的记录,就会发现插入的记录是1,2,2,1,1

从上面可以看出,绑定变量只是起到占位的作用,同名的绑定变量并不意味着在它们是同样的,在传递时要考虑的是传递的值与绑定变量出现顺序的对位,而不是绑定变量的名称。

ORACLE系统本身是能够对变量做绑定的,例如下面的代码:

declare

i number;

begin

for i in 1..1000 loop

insert into tabletest
(i,i+1,i*1,i*2,i-1)

end loop;

end;

这段代码是不需要使用绑定变量的方法来提高效率的,ORACLE会自动将其中的变量绑定。

我们可以这样理解:这段代码执行了1000次的 insert into 测试表 (i,i+1,i*1,i*2,i-1) 语句,每次发出去的语句都是一样的。

如果把这段代码改成如下:

declare

i number;

sqlstr varchar2(200);

begin

for i in 1..1000 loop

sqlstr:='insert
into tabletest
('||to_char(i)||','||to_char(i)||'+1,'||to_char(i)||'*1,'||to_char(i)||'*2,'||to_char(i)||'-1)
';

execute immediate
sqlstr;

end loop;

end;

这段代码同样是执行了1000条insert语句,但是每一条语句都是不同的,因此ORACLE会把每条语句硬解析一次,其效率就比前面那段就低得多了。

如果要提高效率,不妨使用绑定变量将循环中的语句改为

sqlstr:='insert into 测试表 (:i,:i+1,:i*1,:i*2,:i-1) ';

execute immediate
sqlstr using i,i,i,i,i;

这样执行的效率就高得多了。

我曾试着使用绑定变量来代替表名、过程名、字段名等,结果是语句错误,结论就是绑定变量不能当作嵌入的字符串来使用,只能当作语句中的变量来用。

从效率来看,由于oracle10G放弃了RBO,全面引入CBO,因此,在10G中使用绑定变量效率的提升比9i中更为明显。

最后,前面说到绑定变量是在通常情况下能提升效率,那哪些是不通常的情况呢?

答案是:在字段(包括字段集)建有索引,且字段(集)的集的势非常大(也就是有个值在字段中出现的比例特别的大)的情况下,使用绑定变量可能会导致查询计划错误,因而会使查询效率非常低。这种情况最好不要使用绑定变量。

3. TOM大师的书本上的 实例

绑定变量-变更前

declare   
    type rc is ref cursor;
    l_rc rc;
    l_dummy all_objects.object_name%type;
    l_start number default dbms_utility.get_time;
    begin
     for i in 1..1000 loop
     open l_rc for
   'select object_name from all_objects where object_id='||i;
   fetch l_rc into l_dummy;
   close l_rc;
   end loop;
   dbms_output.put_line(round((dbms_utility.get_time-l_start)/100,2)||'seconds...');
   end;
  /

绑定变量-变更后

declare
    type rc is ref cursor;
    l_rc rc;
    l_dummy all_objects.object_name%type;
    l_start number default dbms_utility.get_time;
    begin
     for i in 1..1000 loop
     open l_rc for
   'select object_name from all_objects where object_id=:x' using i;
   fetch l_rc into l_dummy;
   close l_rc;
   end loop;
   dbms_output.put_line(round((dbms_utility.get_time-l_start)/100,2)||'seconds...');
   end;
  /

效果非常明显哦,谢谢大师

oracle-绑定变量学习笔记(未完待续)的更多相关文章

  1. Go web编程学习笔记——未完待续

    1. 1).GOPATH设置 先设置自己的GOPATH,可以在本机中运行$PATH进行查看: userdeMacBook-Pro:~ user$ $GOPATH -bash: /Users/user/ ...

  2. linux学习笔记---未完待续,缓慢更新

    做为linux菜鸟,由于work的需要,慢慢的开始接触学习linux. <鸟哥的linux私房菜>学习笔记. 一.基础命令操作 1.显示日期的命令 date 执行date命令后,显示结果为 ...

  3. jQuery 学习笔记(未完待续)

    一.jQuery概述    宗旨: Write Less, Do More.    基础知识:        1.符号$代替document.getElementById()函数        2.使 ...

  4. Java学习笔记(未完待续)

    变量的作用域(scope)是指变量可以在程序中引用的范围.在方法中定义的变量称为局部变量(local variable).局部变量的作用域从声明变量的地方开始,直到包含该变量的块结束为止.局部变量都必 ...

  5. Greys学习笔记(未完待续)

    Greys介绍 greys-anatomy是一个Java线上诊断工具,取名来自美剧<实习医生格雷>,由菜鸟-杜琨同学开发维护.比我们常用的脚本工具btrace提供更多的功能,greys采用 ...

  6. c++课程学习(未完待续)

    关于c++课程学习 按照计划,我首先阅读谭浩强c++程序设计一书的ppt,发现第一章基本上都是很基础的东西. 同时,书中与班导师一样,推荐了使用visual c++. 而师爷的教程里面推荐使用的是ec ...

  7. Papers | 超分辨 + 深度学习(未完待续)

    目录 1. SRCNN 1.1. Contribution 1.2. Inspiration 1.3. Network 1.3.1. Pre-processing 1.3.2. Patch extra ...

  8. Java并发笔记-未完待续待详解

    为什么需要并行? – 业务要求 – 性能 并行计算还出于业务模型的需要 – 并不是为了提高系统性能,而是确实在业务上需要多个执行单元. – 比如HTTP服务器,为每一个Socket连接新建一个处理线程 ...

  9. Scrapy 爬虫框架学习笔记(未完,持续更新)

    Scrapy 爬虫框架 Scrapy 是一个用 Python 写的 Crawler Framework .它使用 Twisted 这个异步网络库来处理网络通信. Scrapy 框架的主要架构 根据它官 ...

随机推荐

  1. EditText的 焦点事件 setOnFocusChangeListener

    实现代码: //光标处在EditText时其内容消失 mInfo = (EditText)findViewById(R.id.old_password); //setOnFocusChangeList ...

  2. Hibernate之SchemaExport+配置文件生成表结构

    首先要生成表,得先有实体类,以Person.java为例: /** * * @author Administrator * @hibernate.class table="T_Person& ...

  3. 遍历、显示ftp下的文件夹和文件信息

    今天做了通过ftp读取ftp根目录下的所有文件夹和文件,嵌套文件夹查询,总共用到了一下代码: 1.FtpFile_Directory package com.hs.dts.web.ftp; impor ...

  4. 实现对properties文件的有序读写

    最近遇到一项需求,要求把properties文件中的内容读取出来供用户修改,修改完后需要再重新保存到properties文件中.很简单的需求吧,可问题是Properties是继承自HashTable的 ...

  5. 等方案及设备提供商 有需要的可以联系QQ561454825,电话:13779953060,我们提供最专业的无线WIFI认证系统及根据您的需要修改软件

    WayOs智能路由.EasyRadius云计费.POE远程供电.WIFI城中村方案.EPON实现FTTB+LAN城中村方案. 等方案及设备提供商 有需要的可以联系QQ561454825,电话:,我们提 ...

  6. (转载)linux中shell变量

    (转载)http://blog.csdn.net/zahuopuboss/article/details/8633891 为使shell编程更有效,系统提供了一些shell变量.shell变量可以保存 ...

  7. HDU-1527 取石子游戏

    http://acm.hdu.edu.cn/showproblem.php?pid=1527 交换  :可实现. if( n < m ) { n^=m; m^=n; n^=m; } (三)尼姆博 ...

  8. Am命令

    Am.java中: Override public void onRun() throws Exception { mAm = ActivityManagerNative.getDefault(); ...

  9. unity3d shader之God Ray上帝之光

    又是一个post-process后期效果,god ray 上帝之光,说起上帝之光就是咱们再看太阳时太阳周围一圈的针状光芒先放组效果,本文的场景资源均来自浅墨大神,效果为本文shader效果 加入了前篇 ...

  10. this用法

    this是js的一个关键字,随着函数使用场合不同,this的值会发生变化.但是总有一个原则,那就是this指的是调用函数的那个对象. 1.纯粹函数调用. function test() { this. ...