鲜荣彬
Herry

  在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;

  

posted on 2012-03-01 20:57  Herry彬  阅读(351)  评论(0编辑  收藏  举报