Oracle_PL/SQL(5) 包
包
1.定义:包用于逻辑组合相关的PL/SQL类型,项和子程序,由包规范和包体组成
  建立包规范:包规范是包与应用程序之间的接口,用于定义包的公用组件,
    包括常量,变量,游标,过程,函数等
  建立包体:用于实现包规范所定义的过程和函数
2.语法:
包规范只定义不实现
create [or replace] package pkg_name
is
  变量;
  过程;
  函数;
end pkg_name;
包体实现包规范中的定义
create [or replace] package body pkg_name
is
  过程;
  函数;
end pkg_name;
3.举例:
包规范
create or replace package pkg_emp 
is
  v_deptno number(3):=30;
  procedure add_employee(p_eno number,p_ename varchar2,p_sal number,
    p_dno number default v_deptno);
  procedure del_employee(eno number);
  function get_sal(eno number) return number;
end pkg_emp;
/
show err;
包体
create or replace package body pkg_emp 
is 
  --校验部门号是否有效
  function validate_deptno(v_deptno number) return boolean
  is 
    v_cnt number;
  begin
    select count(1) into v_cnt from dept where deptno=v_deptno;
    if v_cnt=1 then
      return true;
    else 
      return false;
    end if;
  end;
  --增加职员
  procedure add_employee(p_eno number,p_ename varchar2,p_sal number,
    p_dno number default v_deptno)
  is 
  begin
    if validate_deptno(p_dno) then
      insert into emp(empno,ename,sal,deptno) values(p_eno,p_ename,p_sal,p_dno);
    else
      raise_application_error(-20001,'不存在该部门');
    end if;
  end;
  --删除职员
  procedure del_employee(eno number) is
  begin
    delete from emp where empno=eno;
    if sql%notfound then 
      raise_application_error(-20012,'该雇员不存在');
    end if;
  end;
  --获取工资
  function get_sal(eno number) return number
  is
    v_sal emp.sal%type;
  begin
    select sal into v_sal from emp where empno=eno;
    return v_sal;
  end;
end pkg_emp;
/
show err;
4.调用包组件
4.1调用包公用变量
  exec pkg_emp.v_deptno:=20
begin 
    --pkg_emp.v_deptno:=20;
    dbms_output.put_line(pkg_emp.v_deptno);
  end;
4.2调用包公用过程
  exec pkg_emp.add_employee(1112,'mary',2000);
  exec pkg_emp.del_employee(1112);
begin 
    pkg_emp.add_employee(1112,'mary',2000);
    --pkg_emp.del_employee(1112);
  end;
4.3调用包公用函数 
  var salary number
  exec :salary:=pkg_emp.get_sal(7788)
declare 
    v_sal number;
  begin 
    v_sal:=pkg_emp.get_sal(7788);
    --select pkg_emp.get_sal(7788) into v_sal from dual;
    dbms_output.put_line('v_sal='||v_sal);
  end;  
4.4 包的私有过程、函数不能被外部调用(只能被包的过程、函数调用)
  如:function validate_deptno(v_deptno number) return boolean
  可以在add_employee内调用,但不能如下被调用。
  declare 
    v_bool boolean;
  begin 
    v_bool:=pkg_emp.validate_deptno(10);
    dbms_output.put_line('v_bool='||v_bool);
  end;    
4.5以其他用户身份调用包公用组件
  connect to sys/123 as sysdba;
  exec scott.pkg_emp.add_employee(1115,'scott',1200);
  exec scott.pkg_emp.del_employee(1115);
4.6调用远程数据库包的公用组件
  exec emp_package.add_employee@orasrv(1116,'scott',1200)
  需要创建db_link
5.查看源代码:存放在数据字典USER_SCOURCE中
  select text from user_source where lower(name)='pkg_emp';
6.删除包
  drop package pkg_emp;
7.使用包重载
  重载(overload)是指多个具有相同名称的子程序。
  包中的函数、过程允许同名,但参数个数、参数类型不能完全相同。
  参数名、、返回值
create or replace package pkg_emp_overload is
  function get_sal(eno number) return number;
  function get_sal(eno varchar2) return number;
end pkg_emp_overload;
/
show err;
7.1建立包规范   
create or replace package pkg_emp_overload is
  function get_sal(eno number) return number;
  function get_sal(name varchar2) return number;
  procedure del_employee(eno number);
  procedure del_employee(name varchar2);
end pkg_emp_overload;
/
show err;
7.2建立包体
  必须要给不同的重载过程和重载函数提供不同的实现代码
create or replace package body pkg_emp_overload is
  function get_sal(eno number) return number
  is 
    v_sal emp.sal%type;
  begin
    select sal into v_sal from emp where empno=eno;
    return v_sal;
  exception
    when no_data_found then
      raise_application_error(-20020,'该雇员不存在');
  end;
function get_sal(name varchar2) return  number
  is
    v_sal emp.sal%type;
  begin
    select sal into v_sal from emp where upper(ename)=upper(name);
    return v_sal;
  exception
    when no_data_found then
      raise_application_error(-20020,'该雇员不存在');
  end;
procedure del_employee(eno number) is
  begin
    delete from emp where empno=eno;
    if sql%notfound then
      raise_application_error(-20020,'该雇员不存在');
    end if;
  end;
procedure del_employee(name varchar2) is
  begin
    delete from emp where upper(ename)=upper(name);
    if sql%notfound then
      raise_application_error(-20020,'该雇员不存在');
    end if;
  end;
end pkg_emp_overload;
/
show err;
7.3 调用重载过程和重载函数
  var sal1 number;
  var sal2 number;
  exec :sal1:=pkg_emp_overload.get_sal('scott');
  exec :sal2:=pkg_emp_overload.get_sal(7685);
  exec pkg_emp_overload.del_employee(7369);
  exec pkg_emp_overload.del_employee('scott');
8.使用包构造过程
  包构造过程用于给包变量赋值。
  包的构造过程没有任何名称,它是实现了包的其他过程后,
  以BEGIN开始,END结束的部分,
  在包体中给包变量赋值。
8.1建立包规范
  --包的构造过程用于初始化包的全局变量.
  在包规范中定义包变量。
create or replace package pkg_emp_construction is
  minsal number(6,2);
  maxsal number(6,2);
  procedure add_employee(eno number,name varchar2,
    salary number,dno number);
  procedure upd_sal(eno number,salary number);
  procedure upd_sal(name varchar2,salary number);
end pkg_emp_construction;
/
show err;
8.2 建立包体
  包的构造过程没有任何名称,它是实现了包的其他过程后,
  以BEGIN开始,END结束的部分,
  在包体中给包变量赋值。
create or replace package body pkg_emp_construction 
is
  procedure add_employee(eno number,name varchar2,salary number,dno number)
  is
  begin
    if salary between minsal and maxsal then
      insert into emp (empno,ename,sal,deptno) values(eno,name,salary,dno);
    else
      raise_application_error(-20001,'工资不在范围内');
    end if;
  exception
    when dup_val_on_index then
      raise_application_error(-20002,'该雇员已经存在');
  end;
procedure upd_sal(eno number,salary number) is
  begin
    if salary between minsal and maxsal then
      update emp set sal=salary where empno =eno;
      if sql%notfound then
        raise_application_error(-20003,'不存在雇员号');
      end if;
    else
      raise_application_error(-20001,'工资不在范围内');
    end if;
  end;
procedure upd_sal(name varchar2,salary number) is
  begin
    if salary between minsal and maxsal then
      update emp set sal=salary where upper(ename)=upper(name);
      if sql%notfound then
        raise_application_error(-20004,'不存在该雇员名');
      end if;
    else
      raise_application_error(-20001,'工资不在范围内');
    end if;
  end;
begin
  select min(sal),max(sal) into minsal,maxsal from emp ;
end pkg_emp_construction;
/
show err;
8.3 调用包公用组件:构造过程只调用一次
  exec pkg_emp_construction.add_employee(1117,'mary',3000,20);
begin 
    dbms_output.put_line('minsal='||pkg_emp_construction.minsal);
    dbms_output.put_line('maxsal='||pkg_emp_construction.maxsal);
  end;
exec pkg_emp_construction.upd_sal('mary',2000);
--只定义包规范
create or replace package pkg_var is
  minsal number(6,2);
  maxsal number(6,2);
end pkg_var;
/
show err;
9.作业
9.1 针对dept表做一个包
包括新增部门、修改部门、删除部门,
包括返回部门名、返回loc。
9.2 将转账业务改造成包,要求如下:
包括三个过程 转入、转出、记日志(私有过程);
包括两个函数(参数为账户) 转入金额、转出金额。
并编写单独的过程调用包进行转入、转出操作;
通过sql调用函数,输出 转入金额、转出金额。
Oracle_PL/SQL(5) 包的更多相关文章
- PL/SQL --> 动态SQL调用包中函数或过程
		
动态SQL主要是用于针对不同的条件或查询任务来生成不同的SQL语句.最常用的方法是直接使用EXECUTE IMMEDIATE来执行动态SQL语句字符串或字符串变量.但是对于系统自定义的包或用户自定的包 ...
 - PL/SQL之--包
		
一.包 包是一组相关过程.函数.常量.变量.游标.异常等PL/SQL程序设计元素的组合.它类似于C++和Java中的类,其中变量相当于类中的成员变量,过程和函数相当于类中的方法.通过使用包,可以使开发 ...
 - Oracle_PL/SQL(9) 例外处理
		
例外处理1.例外分类:预定义例外,非预定义例外,自定义例外三种传递例外:如果在例外处理部分exception没有捕捉例外,oracle会将例外传递到调用环境.捕捉并处理例外:使用例外处理部分完成exc ...
 - Oracle_PL/SQL(4) 过程和函数
		
create table s_sc ( SNAME VARCHAR2(20) primary key, c_grade NUMBER(6), m_grade NUMBER(6), e_grade NU ...
 - Oracle_PL/SQL(3) 游标
		
引言:PLSQL数据类型标量数据类型:数字类.字符类.日期类.布尔类(boolean).复合数据类型:记录(%rowtype).表.数组引用类型:REF CURSORLOB类型:BLOB.CLOB 1 ...
 - Oracle_PL/SQL(1) 匿名块
		
1. PL/SQL 简介PL/SQL是一种比较复杂的程序设计语言, 用于从各种环境中访问Oracle数据库.为什么使用PL/SQL?Orade是一种关系型数据库, 用来访问关系型数据库的语言是 “结构 ...
 - PL/SQL之包
		
1.包的定义 一个包由两个独立的部分组成--包头和包体.给部分被单独地存放在数据字典中. .1定义包头 语法: CREATE [OR REPLACE] PACKAGE [schema.] packag ...
 - PL/SQL编程—包
		
1.PLSQL 中的包就相当于java中的package,主要好处有(1)防止命名污染,(2)功能统一,(3)允许重载,(4)可以隐藏核心代码,(5)最重要的就是断开依赖链. 2.对于一个程序需要大量 ...
 - Oracle_PL/SQL(10) 定时器job
		
定时器job1.定义 定时器指在特定的时间执行特定的操作. 可以多次执行.说明:特定的操作:指一个完成特定功能的存储过程.多次执行:指可以每分钟.每小时.每天.每周.每月.每季度.每年等周期性的运行. ...
 
随机推荐
- 在Centos 6.5 X64下切割m3u8
			
操作系统:centos 6.5 必需要参考的文章: http://blog.chinaunix.net/uid-23069658-id-4018842.html 准备工作: 安装git yum ins ...
 - QuickSand图片点击后分裂成几份消失效果《IT蓝豹》
			
QuickSand图片点击后分裂成几份消失效果 QuickSand图片点击后分裂成几份消失效果,适合做图片退出和剪切效果.同时也可以学习android动画. demo中都封装好几个功能类,主要动画实现 ...
 - Spring Data MongDB空间索引(判断一个点Point是否在一个区域Polygon内)
			
这里要连接MongoDB数据库,在配置文件里:spring.data.mongodb.uri = mongodb://root:root@localhost:27017/happy 两个root分别是 ...
 - Jenkins  踩过的坑之再总结
			
在安装完jenkins后,linux中默认使用的jenkins这个用户,这时在构建完项目后我们需要执行一些shell命令时会出现没有权限的情况,导致构建失败,这里我们需要给jenkins用户相应的权限 ...
 - 获取url后面的参数的方法
			
1. function GetRequest() { var url = 'http://wwww.jb51.net/?q=js'; //获取url中"?"符后的字串 if (ur ...
 - 使用openshit在ubuntu14.04下一键部署openstack(juno版本)
			
一.基本介绍 本实验是在vmware workstation上虚拟机ubuntu14.04(64bit,desktop)上部署openstack(Juno版本).采用的工具是openshit.open ...
 - 使用JavaMail发送邮件-no object DCH for MIME type multipart/mixed报错解决
			
最近需要实现一个使用Spring schedule按一定时间间隔自动触发条件发送邮件的功能,在开发的过程中,是按照先测试能发出text/html文本邮件,然后测试添加附件发送邮件,我碰到的问题是,文本 ...
 - 单元测试框架unittest
			
单元测试:单元测试,是指对软件中的最小可测试单元进行检查和验证,对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义如:c语言中单元指一个函数,java里单元指一个类,图形化的软件中可以 ...
 - ORA-30926: 无法在源表中获得一组稳定的行ORA-06512: 在 "STG.FP_MO_SPLIT", line 1562 临时
 - html自定义弹框
			
一.要实现的功能 1.弹框弹出时有遮罩 2.弹框内的文字过多时右侧有滚动条 3.根据执行结果变更弹框title的样式 二.具体实现 思路:定义一个有宽高的div,默认隐藏,当要显示时,设置为dis ...