Oracle12C--包(四十七)

知识点的梳理:
  • 通过包可以实现多种程序结构的统一管理,包分为两个部分,即包规范,包体,只有在包规范中定义的程序结构才可以被其他程序所使用;
  • 包中的子程序支持重载,只需要考虑参数以及个数的不同即可;
  • 包中程序的纯度有4 种级别:WNDS,RNDS,WNPS,RNPS

      

  • 包的基本概念
    • 包是一种程序模块化设计的实现手段。通过包将一个模块所需要的程序(过程,函数,游标,类型)结构统一管理,同时包与包之间也可以互相调用;
    • 定义包需要两个组成部分:
      • 包规范(PACKAGE):定义包中可以被外部访问的部分,在包规范中声明的内容可以从应用程序和包的任何地方访问,语法:

CREATE OR [REPLACE] PACKAGE 包名称
[AUTHID CURRENT_USER | DEFINER]
IS | AS
结构名称定于(类型,过程,函数,游标,异常等)
END [包名称];
/

[AUTHID CURRENT_USER | DEFINER]为权限设置,

如果包规范中的某个操作可以由使用者权限决定,则将其设置为CURRENT_USER
在包规范中所定义的所有子程序权限必须与包规范声明时定义的权限相同

 

  • 包体(PACKAGE BODY):负责包规范中定于的函数或过程的具体实现代码,如果在包体中定义了包规范中没有的内容,则此部分内容将被设置为私有访问,包体的定义语法如下:

CREATE OR [REPLACE] PACKAGE BODY 包名称
IS |AS
结构实现(类型,过程,函数,游标,异常等)
BEGIN
包初始化程序代码;
END [包名称];
/

  • 示例1:定义包规范

CREATE OR REPLACE PACKAGE mldn_pkg

AS

FUNCTION get_emp_fun(p_dno dept.deptno%TYPE) RETURN SYS_REFCURSOR ; --返回弱游标类型

END ;

/

分析:
定义了一个包规范,此规范定义了一个
get_emp_fun()函数,该函数可被任何应用程序调用,该函数的返回值类型为SYS_REFCURSOR

方法2:自己定义弱类型游标

CREATE OR REPLACE PACKAGE mldn_pkg

AS

TYPE cursor_ref IS REF CURSOR ;

FUNCTION get_emp_fun(p_dno dept.deptno%TYPE) RETURN cursor_ref ;

END ;

/

  

  • 示例2:定义包体实现get_emp_fun()函数

CREATE OR REPLACE PACKAGE BODY mldn_pkg

AS

FUNCTION get_emp_fun(p_dno dept.deptno%TYPE) RETURN SYS_REFCURSOR

AS

cur_var SYS_REFCURSOR ;

BEGIN

OPEN cur_var FOR SELECT * FROM emp WHERE deptno=p_dno ; --打开参数游标

RETURN cur_var ;

END ;

END ;

/

方法2:自定义游标变量

CREATE OR REPLACE PACKAGE BODY mldn_pkg

AS

FUNCTION get_emp_fun(p_dno dept.deptno%TYPE) RETURN cursor_ref

AS

cur_var cursor_ref ;

BEGIN

OPEN cur_var FOR SELECT * FROM emp WHERE deptno=p_dno ; --打开参数游标

RETURN cur_var ;

END ;

END ;

/

  • 通过user_objects与user_source查询包的信息
    • 示例1:查询user_objects数据字典确认包规范及包体信息

SELECT object_type , object_name , status FROM user_objects

WHERE object_type IN ('PACKAGE','PACKAGE BODY') ;

  • 示例2:查询user_source数据字典,查看包规范

SELECT *

FROM user_source

WHERE type='PACKAGE' AND name='MLDN_PKG' ;

  • 包的调用
    • 示例1:定义PL/SQL程序块调用包中的函数

DECLARE

v_receive SYS_REFCURSOR ;

v_empRow emp%ROWTYPE ; --定义行类型

BEGIN

v_receive := mldn_pkg.get_emp_fun(10) ;

LOOP

FETCH v_receive INTO v_empRow ; --取得游标数据

EXIT WHEN v_receive%NOTFOUND ; --如果没有数据则退出

DBMS_OUTPUT.put_line('雇员姓名:' || v_empRow.ename || ',雇员职位:' || v_empRow.job) ;

END LOOP ;

END ;

/

  

  • 示例2:如果不使用SYS_REFCURSOR,则在声明v_receive变量时,就需要通过包定义类型

DECLARE

v_receive mldn_pkg.cursor_ref ;

v_empRow emp%ROWTYPE ; --定义行类型

BEGIN

v_receive := mldn_pkg.get_emp_fun(10) ;

LOOP

FETCH v_receive INTO v_empRow ; --取得游标数据

EXIT WHEN v_receive%NOTFOUND ; --如果没有数据则退出

DBMS_OUTPUT.put_line('雇员姓名:' || v_empRow.ename || ',雇员职位:' || v_empRow.job) ;

END LOOP ;

END ;

/

  

  • 删除包
    • 删除包规范语法:

DROP PACKAGE 包名称;

  • 删除包体

DROP PACKAGE BODY 包名称;

  • 示例1:删除mldn_pkg包

DROP PACKAGE mldn_pkg ;

此时删除的是包规范,删除的同时包体会一并删除

  • 重新编译包
    • 语法:

ALTER PACKAGE 包名称 COMPILE [DEBUG] PACKAGE | SPECIFICATION | BODY [REUSE SETTINGS];

  • 包的重新编译有3种编译形式:

PACKAGE

重新编译包规范和包体

SPECIFICATION

重新编译包规范

BODY

重新编译包体

  • 示例1重新编译包规范

ALTER PACKAGE mldn_pkg COMPILE SPECIFICATION ;

  • 示例2重新编译包体

ALTER PACKAGE mldn_pkg COMPILE BODY ;


  •   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值