您的位置:首页 > 数据库 > Oracle

oracle 学习笔记(四)

2012-03-01 20:57 232 查看
  在oracle中有一个很重要的东东---包,package。(本文中的代码都是在SCOTT中emp表中实现的)

  引用他人的定义--包是一种数据库对象,将逻辑上相关的PL/SQL类型、对象和子程序组合成一个更大的单位。包有两个部分:包说明(specification)和包体(body)。说明部分是为应用程序的接口,它申明类型、常量、例外、游标和可用的子程序。体定义游标和子程序,实现说明。应用程序仅对包说明中的申明是可见的和可存取。如果ORACLE具有Procedure选件,包可以编译、存贮在ORACLE数据库中,其内容可为许多应用共享。当用户第一次调用一包装的子程序时,整个包装入到内存,所以在以后对包中子程序调用时,不再需要I/O操作,故包可提高效率和改进性能。

  我个人的理解是--我们可以在包中写存储过程、函数,这是我们最常用的。那么包中到底可以有什么东西了,如下图,这是在oracle数据库中截取的,应该更有说服力。     



在oracle中有一个包 dbms_output,我们就可以调用在这个包中的函数 put_line。

包分为包说明和包体,下面就分别创建一个包说明和包体,

create or replace package sp_package is   --注意,这里包的名字是 sp_package,后面要用关键字 is
procedure update_sal(name emp.ename%type,newsal emp.sal%type);  --定义了一个存储过程
function income(name emp.ename%type) return number;   --定义了一个函数,返回值数据类型是整形的
end;


包体

create or replace package body sp_package is

procedure update_sal(name emp.ename%type,newsal emp.sal%type) is  --具体实现包说明中的存储过程
begin
update emp set sal=newsal where ename=name;
end;

function income(name emp.ename%type)  --具体说明包说明中的函数
return number is salary number;
begin
select sal*12 into salary from emp where ename=name;
return salary;
end;

end;

 call sp_package.update_sal('MILLER',1500); --调用这个包中的存储过程,当然如果要访问其他方案的包,还要在包的前面加上方案名。
如果有异常,则自己处理吧。

 在以上的sql语句,我们返回的都是一个值,没有返回多个值,如果返回的是多个值呢,我们应该用什么容器去承载它,oracle有一个概念,叫做复合变量,用于存放多个值的变量,包括pl/sql 记录,pl/sql 表,嵌套表,varray;

  PL/SQL 记录:下面的sql语句就定义了一个record(记录) emp_record_type,他可以承载姓名,工资,工作类型,是一个记录喔!定义一个记录的格式是

declare type 记录名 is record(...);这和C语言中的结构定义比较相像。

declare
type emp_record_type is record(  --这里你需要注意书写的格式是什么
name emp.ename%type,
salary emp.sal%type,
title emp.job%type);
emp_record  emp_record_type;  --定义了一个emp_record_type类型的变量 emp_record
begin
select ename,sal,job into emp_record from emp where empno=7782;
dbms_output.put_line(emp_record.name);
end;


  PL/SQL记录表相当于数组,高级语言里的数组的下表不能为负数,但此时的数组的下标可以是负数,只是没有值罢了。定义记录表的格式是

declare type 记录表名 is table of 承载内容 index by binary_integer;

declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
select ename into sp_table(0) from emp where empno=7788;
dbms_output.put_line(sp_table(0));
end;


参照变量是指用于存放数值指针的变量,通过使用参照变量,可以使得应用程序共享相同对象,从而降低使用空间,在编写的时候,可以使用游标变量(ref cursor)和对象类型变量(ref obj_type) 两种参照变量类型。使用游标 当定义游标时不需要指定相应的select语句,但是当使用游标时需指定select语句,这样就和select语句结合了。

declare
2  --定义游标类型
3  type sp_emp_cursor is ref cursor;
4  --定义游标变量
5  test_cursor sp_emp_cursor;
6  --定义变量
7  v_ename emp.ename%type;
8  v_sal emp.sal%type;
9  begin
10  --执行
11  open test_cursor for select ename,sal from emp where deptno=&no; ---格式 open 游标变量名 for sql语句
12  loop                   ---循环读取游标中的值  注意loop的用法 loop....end loop。
13  fetch test_cursor into v_ename,v_sal;  --读取内容,放在变量里面,注意这里存放的顺序,v_ename to ename,v_sal to sal
14  exit when test_cursor%notfound;   --如果没有数据,退出循环
15  dbms_output.put_line(v_ename||v_sal);
16  end loop;
17  --close test_cursor; --这里关闭游标和打开游标时不同的,在Java里面调用,我测试的是如果有这句,则不能读取数据,你可以试试
18  end;


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: