zoukankan      html  css  js  c++  java
  • 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调用函数,输出 转入金额、转出金额。

  • 相关阅读:
    【C#】C#获取文件夹下的所有文件
    6 云计算系列之Nova安装与配置
    5 云计算系列之glance镜像服务安装
    4 云计算系列之Openstack简介与keystone安装
    3大数据挖掘系列之文本相似度匹配
    6 Django系列之关于models的sql语句日常用法总结
    2 python大数据挖掘系列之淘宝商城数据预处理实战
    5 Django系列之通过list_display展示多对多与外键内容在admin-web界面下
    1 python大数据挖掘系列之基础知识入门
    4 django系列之HTML通过form标签来同时提交表单内容与上传文件
  • 原文地址:https://www.cnblogs.com/BradMiller/p/9279590.html
Copyright © 2011-2022 走看看