学习要求
有一定关系型数据的操作功底,会SQL语句
教学目标
熟练掌握Oracle数据库PL/SQL编程中包的操作
概念
包是一组相关过程、函数、变量、常量和游标等 PL/SQL 程序设计元素的组合,它具有面向对象程序设 计语言的特点,是对这些 PL/SQL 程序设计元素的封装。包类似于 JAVA 中的类,其中变量相当 于类中的成员变量,过程和函数相当于类方法。把相关的模块归类成为包,可使开发人员利用面向对象的 方法进行存储过程的开发,从而提高系统性能。
一个包由两个分开的部分组成:
包定义(PACKAGE):包定义部分声明包内数据类型、变量、常量、游标、子程序和异常错误处理等元 素,这些元素为包的公有元素。
包主体(PACKAGE BODY):包主体则是包定义部分的具体实现,它定义了包定义部分所声明的游标和子 程序,在包主体中还可以声明包的私有元素。
包定义和包主体分开编译,并作为两部分分开的对象存放在数据库字典中,详见数据字典 user_source, all_source, dba_source.
包定义
CREATE [OR REPLACE] PACKAGE package_name
[AUTHID {CURRENT_USER | DEFINER}]
{IS | AS}
[公有数据类型定义[公有数据类型定义]…]
[公有游标声明[公有游标声明]…]
[公有变量、常量声明[公有变量、常量声明]…]
[公有子程序声明[公有子程序声明]…]
END [package_name]
包主体
CREATE [OR REPLACE] PACKAGE BODY package_name
{IS | AS}
[私有数据类型定义[私有数据类型定义]…]
[私有变量、常量声明[私有变量、常量声明]…]
[私有子程序声明和定义[私有子程序声明和定义]…]
[公有游标定义[公有游标定义]…]
[公有子程序定义[公有子程序定义]…]
BEGIN
PL/SQL 语句
END [package_name];
其中:在包主体定义公有程序时,它们必须与包定义中所声明子程序的格式完全一致
操作注意:
1 包说明和包体必须有相同的名字
2 包的开始没有begin语句,与存储过程和函数不同。
3 在包的说明部分定义函数和过程的名称和参数,具体实现在包体中定义。
4 在包内声明常量、变量、类型定义、异常、及游标时不使用declare。
5 包内的过程和函数的定义不要create or replace语句。
6 包声明和包体两者分离。
需求:定义一个包,能满足部门的crud
-- 包定义
create or replace package dept_op
is
totalCount number;
function add(dno number, dn varchar2, dloc varchar2) return number;
function remove(dno number) return number;
function edit(dno number, dn varchar2, dloc varchar2) return number;
procedure get(dno number);
procedure list;
end dept_op;
-- 包体定义
create or replace package body dept_op
is
-- 添加
function add(dno number, dn varchar2, dloc varchar2) return number
is
begin
insert into dept(deptno, dname, loc) values(dno, dn, dloc);
return 1;
Exception
when dup_val_on_index then
dbms_output.put_line ('id已经存'); -- id冲突
return 0;
end;
-- 删除
function remove(dno number) return number
is
v_count number;
begin
select deptno into v_count from dept where deptno = dno;
delete from dept where deptno = dno;
return 1;
Exception
when no_data_found then
dbms_output.put_line('deptno:' || dno ||'的数据不存在,不能删除');
return 0;
end;
-- 编辑
function edit(dno number, dn varchar2, dloc varchar2) return number
is
v_count number;
begin
select deptno into v_count from dept where deptno = dno;
update dept set dname = dn, loc = dloc where deptno = dno;
return 1;
exception
when no_data_found then
dbms_output.put_line('deptno:' || dno ||'的数据不存在,不能编辑');
return 0;
end;
-- 查单个
procedure get(dno number)
is
v_dept dept%rowtype;
begin
select * into v_dept from dept where deptno = dno;
dbms_output.put_line(v_dept.deptno || '***' || v_dept.dname || '***' || v_dept.loc);
end;
-- 查所有
procedure list
is
cursor c_cursor is select deptno, dname, loc from dept;
begin
for v_dept in c_cursor loop
dbms_output.put_line(v_dept.deptno || ' --- ' || v_dept.dname || '---' ||v_dept.loc);
end loop;
end;
end dept_op;
测试
-- 调用
-- 添加
declare
v_ret number;
begin
v_ret := dept_op.add(10, '小卖部', '广州');
if v_ret = 1 then
dbms_output.put_line('添加成功');
else
dbms_output.put_line('添加失败');
end if;
end;
-- 更新
declare
v_ret number;
begin
v_ret := dept_op.edit(90, '大卖部', '深圳');
if v_ret = 1 then
dbms_output.put_line('更新成功');
else
dbms_output.put_line('更新失败');
end if;
end;
-- 删除
declare
v_ret number;
begin
v_ret := dept_op.remove(90);
if v_ret = 1 then
dbms_output.put_line('删除成功');
else
dbms_output.put_line('删除失败');
end if;
end;
-- 查单个
exec dept_op.get(10);
-- 查所有
exec dept_op.list;
PL/SQL开发包
删除包
删除包之后,会自动删除包体
-- 语法
DROP PACKAGE [BODY] [user.]package_name
-- 删除dept_op
drop package dept_op;