oracle 包的使用,我的宝~

1、包的概念性问题

包是一组相关过程、函数、变量、常量和游标等pl/sql程序设计元素的组合,它具有面向对象程序设计语言的特点,是对这些程序单元的封装。

包分为包定义(包规范、包头)和包体两部分

包定义包括数据类型、变量、常量、游标、子程序和异常等元素,这些元素为包的公有元素。
包体则是包定义部分的具体实现,它定义了包定义部分所声明的游标和子程序,在包体中还可以声明包的私有元素。

2、包定义(包规范、包头)与包体

包定义语法:
create or replace package package _name is|as
<定义公有变量、常量、类型、游标>
<定义公有过程和函数>
end;

包体:
用于实现包定义所规范的公有过程和函数。并且可以定义包内的私有组件。

语法:create or replace package body package_name is|as
<定义私有变量、常量、类型、游标、过程和函数>
<实现公有过程和函数>
end;

包体名称必须与包定义名称相同在包体定义公有子程序时,它们必须与包定义中所声明子程序的格式完全一致。

3、课堂练习:定义包规范(就是包定义),分别定义存储过程完成部门信息的添加和删除操作,定义函数实现根据传递的部门号返回部门信息。

方案一:

create or replace package dept_pack 
is/as
-- 包含了过程、包含了函数
procedure add_rec(dept_rec dept%rowtype); --输入(in)类型的,输入一条记录进去
--procedure del_rec(dno dept.deptno%type); -- 输入类型的变量
--function get_rec(dno dept.deptno%type) return dept%rowtype; --记录类型的变量
end;

-- 上面的就是包头!
-- 下面定义包体!

create or replace package body dept_pack 
as
function check_rec(dno deptno.deptno%type) return boolean is   --定义在包体中,就是私有变量,用来检查记录
fcount number;   --接收值的一个变量
begin
	select count(*) into fcount from dept where deptno=dno;
	if fcount=0 then
		return false;
	else
		return true;
	end if;
end;

procedure add_rec(dept_rec dept%rowtype) 
is
begin
	if check_rec(dept_rec.deptno)=false then
		insert into dept values(dept_rec.deptno,dept_rec.dname,dept)rec.loc);
	else
		dbms_output.put_line('部门已存在');
	end if;
end;

--procedure del_rec(dno dept.deptno%type) 
--is
--begin
--end;
end;

使用匿名块调用包头:

declare 
	dept_rec dept%rowtype;
begin
	dept_rec.deptno :=90;
	dept_rec.dname :='jingji';
	dept_rec.loc := 'yantai';
	dept_pack.add_rec(dept_rec);   --使用dept_pack.(包名➕. )来完成调用。
end;

方案二:

定义包规范(就是包定义),分别定义存储过程完成部门信息的添加和删除操作,定义函数实现根据传递的部门号返回部门信息。

create or replace package dept_pack
is
procedure add_dept(dept_rec dept% rowtype);
procedure del_dept(p_no dept.deptno%type);
function get_dept(p_no dept.deptno% TYPE)
return dept%rowtype;
end;

定义包体,实现上面的包规范
提示:因下面的代码包含了两个过程和两个函数,调试不方便。建议先单独写每个函数和过程,分别调试,没有错误后,再复制合并。

create or replace package body dept_pack is
/*check_dept是包的私有子程序*/
function check_dept(p_dno dept.deptno% TYPE)
RETURN boolean is
f_count NUMBER;
begin
  select count(*) into f_count from dept where deptno= p_dno;
  if f_count>0 THEN
    RETURN true;
  else
    return false;
  end if;
end;
--实现add_dept过程
procedure add_dept(dept_rec dept%rowtype) is
begin
  if check_dept(dept_rec.deptno)=false THEN
    insert into dept values(dept_rec.deptno,dept_rec.dname,dept_rec.loc);
    dbms_output.put_line('插入成功');
  else
    dbms_output.put_line('插入失败,部门号已经存在');
  end if;
end;
--实现del_dept过程 
procedure del_dept(p_no dept.deptno% TYPE) is
begin
  if check_dept(p_no)=true THEN
    DELETE from dept where deptno= p_no;
    dbms_output.put_line('删除成功');
  else 
    dbms_output.put_line('删除失败,无此部门');
  end if;
end;
--实现get_dept
function get_dept(p_no dept.deptno% TYPE)
return dept%rowtype;
is
rec_dept dept%rowtype;
no_result EXCEPTION;
begin 
  if check_dept(p_no)=true THEN
    select * into rec_dept from dept where deptno= p_no;
    return rec_dept;
  else 
    raise no_result;
  end if;
  exception
    when no_result THEN
      dbms_output.put_line('部门不存在');
    when others THEN
      dbms_output.put_line('查询出错');
end;      
end;

包的调用:当在其它应用程序或PL/SQL语句块中调用包的变量、函数或存储过程时,需在它们名字之前加包名,并用点号连接。即:包名.公有元素名
上面包中过程和函数的调用:

set serveroutput on

declare
rec_d dept%rowtype;
begin
--插入记录
rec_d.deptno:=&no;
rec_d.dname:='&dname';
rec_d.loc:='&loc';
dept_pack.add_dept(rec_d);
--删除记录
dept_pack.del_dept(80);
--获取部门信息,注意函数调用是有返回值的,不能直接写函数名调用
rec_d:=dept_pack.get_dept(99);
dbms_output.put_line(rec_d.deptno ||' '||rec_d.dname ||' '||rec_d.loc);
end;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱睡觉的小馨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值