• pl/sql学习(4): 包package


    本文简单介绍包, 目前来看我用的不多, 除了之前 为了实现 一个procedure 的输出参数是结果集的时候用到过 package.

    概念: 包是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合。

    特点: 它具有面向对象程序设计语言的特点,是对PL/SQL程序设计元素(过程、函数、变量等)的封装。它使程序设计模块化。

    包中的程序元素分为两种:公用元素(公用组件)、私用元素(私用组件).

    组成: 一个包由两个分开的部分组成

    (1) 包规范(包定义):用于定义包的公用组件,包括常量、变量、游标、过程和函数等。

    (2) 包体(包主体):用于实现包规范所定义的公用过程和函数。

    包体不仅可用于实现公用过程和函数,而且还可以定义包的私有组件(变量、游标、过程、函数等)

    创建包规范语法

    CREATE [OR REPLACE] PACKAGE package_name
    IS | AS
    -- 定义公用常量、变量、游标、过程、函数等
    END [package_name];

    实例1:

    CREATE OR REPLACE PACKAGE emp_package
    IS
                 --添加员工信息的存储过程
                 PROCEDURE add_emp_proc
                 (v_empno IN emp.empno%TYPE,
                 v_ename IN emp.ename%TYPE,
                 v_sal IN emp.sal%TYPE,
                 v_deptno IN emp.deptno%TYPE);
    
             --删除员工信息的存储过程
             PROCEDURE del_emp_proc (v_empno IN emp.empno%TYPE);
    END emp_package;

    创建包体的语法

    CREATE [OR REPLACE] PACKAGE BODY package_name 
    IS | AS
    --定义私有常量、变量、游标、过程和函数等
    --实现公用过程和函数
    END [package_name];

    调用包:  包名.元素名称

    删除包: DROP PACKAGE [BODY] [user.] package_name;

    实例2: 

    CREATE OR REPLACE PACKAGE BODY emp_package
    IS    
                --添加员工信息的存储过程
                 PROCEDURE add_emp_proc
                 (v_empno IN emp.empno%TYPE,
                 v_ename IN emp.ename%TYPE,
                 v_sal IN emp.sal%TYPE,
                 v_deptno IN emp.deptno%TYPE)
                 IS
                                    e_2291 EXCEPTION;
                                    PRAGMA EXCEPTION_INIT(e_2291, -2291);
                 BEGIN
                     INSERT INTO emp(empno, ename, sal, deptno) 
    VALUES(v_empno, v_ename, v_sal, v_deptno); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN RAISE_APPLICATION_ERROR(-20001, '员工号不能重复'); WHEN e_2291 THEN RAISE_APPLICATION_ERROR(-20002, '部门号不存在'); END; --删除员工信息的存储过程 PROCEDURE del_emp_proc (v_empno IN emp.empno%TYPE) IS BEGIN --根据员工号删除指定的员工信息 DELETE FROM emp WHERE empno = v_empno; --判断是否删除成功 IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20009, '指定删除的员工不存在'); ELSE DBMS_OUTPUT.PUT_line('删除成功'); END IF; END; END emp_package;

    调用上述包-->员工信息存储过程

    DECLARE 
        v_empno emp.empno%TYPE := &empno;
        v_ename emp.ename%TYPE := '&name';
        v_sal emp.sal%TYPE := &salary;
        v_deptno emp.deptno%TYPE := &deptno;
        e_dup_val EXCEPTION;
        e_no_dept EXCEPTION;
    
        PRAGMA EXCEPTION_INIT(e_dup_val, -20001);
        PRAGMA EXCEPTION_INIT(e_no_dept, -20002);
    BEGIN
        emp_package.add_emp_proc(v_empno, v_ename, v_sal, v_deptno);
        COMMIT;
    EXCEPTION
        WHEN e_dup_val THEN
            DBMS_OUTPUT.put_line(SQLERRM);
        WHEN e_no_dept THEN
            DBMS_OUTPUT.put_line(SQLERRM);
            ROLLBACK;
    END;

    调用上述包-->删除过程

    DECLARE 
        v_empno emp.empno%TYPE := &empno;
        e_no_emp EXCEPTION;
        PRAGMA EXCEPTION_INIT(e_no_emp, -20009);
    BEGIN
        emp_package.del_emp_proc(v_empno);-- 调用包中的删除过程
        COMMIT;
    EXCEPTION
        WHEN e_no_emp THEN
            DBMS_OUTPUT.put_line(SQLERRM);
            ROLLBACK;
    END;

    综合实例1: 创建包规范和包体

    --创建包规范
    CREATE OR REPLACE PACKAGE package1
    IS
        v_no emp.deptno%TYPE := 10;
        --过程
        PROCEDURE query_emp(v_deptno IN NUMBER DEFAULT v_no, v_avgsal OUT NUMBER,
    v_cnt OUT NUMBER); END package1; --创建包体 CREATE OR REPLACE PACKAGE BODY package1 IS PROCEDURE query_emp(v_deptno IN NUMBER DEFAULT v_no, v_avgsal) OUT NUMBER,
    v_cnt OUT NUMBER) IS BEGIN SELECT avg(sal), count(*) INTO v_avgsal, v_cnt FROM emp
    WHERE deptno = v_deptno; EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('没有此部门'); WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END; END package1;

    调用包中的存储过程  语法为: 包名.元素名称(组件名称)

    DECLARE
        v_avgsal NUMBER;
        v_cnt NUMBER;
    BEGIN
        package1.query_emp(20, v_avgsal, v_cnt);
        DBMS_OUTPUT.put_line('平均工资:' || v_avgsal);
        DBMS_OUTPUT.put_line('总人数:' || v_cnt);
    END;

    综合实例2: 根据员工号查询工资,如果工资小于等于3000,工资涨500。

    --创建包规范
    CREATE OR REPLACE PACKAGE emp_sal_pkg
    IS
        FUNCTION get_sal(eno NUMBER) RETURN NUMBER;
    
        PROCEDURE upd_sal(eno NUMBER, salary NUMBER);
    END emp_sal_pkg;
    
    --包体
    CREATE OR REPLACE PACKAGE BODY emp_sal_pkg
    IS
        FUNCTION get_sal(eno NUMBER) RETURN NUMBER
        IS
            v_sal emp.sal%TYPE := 0;
        BEGIN
            SELECT sal INTO v_sal FROM emp WHERE empno = eno;
            RETURN v_sal;
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RAISE_APPLICATION_ERROR(-20010,'此员工号不存在');
        END;
    
        PROCEDURE upd_sal(eno NUMBER, salary NUMBER)
        IS
        BEGIN
            IF salary <=3000 THEN
                UPDATE emp SET sal = sal + 500 WHERE empno = eno;
            END IF;
        END;
    END emp_sal_pkg;  

    调用上述包:

    DECLARE
        v_empno emp.empno%TYPE := &empno;
        v_salary emp.sal%TYPE;
        e_no_emp EXCEPTION;
        PRAGMA EXCEPTION_INIT(e_no_emp, -20010);
    BEGIN
        v_salary := emp_sal_pkg.get_sal(v_empno); --调用包中的函数
        emp_sal_pkg.upd_sal(v_empno, v_salary);--调用包中的过程
        COMMIT;
    EXCEPTION
        WHEN e_no_emp THEN
            DBMS_OUTPUT.put_line(SQLERRM);
    END;
    ----END---- HAVE A GOOD ONE! 以上为本人课余自学工具书/blog的笔记整理, 常有更新, 非100%原创!且读且学习。
  • 相关阅读:
    linux下自动同步internet时间
    String,StringBuffer与StringBuilder的区别
    Spring Boot CLI安装
    java中Date与String的相互转化
    MyBatis Sql语句中的转义字符
    MyBatis详解 与配置MyBatis+Spring+MySql
    MyBatis的foreach语句详解
    不可变集合 Immutable Collections
    Java日期时间使用总结
    Java将一段逗号分割的字符串转换成一个数组
  • 原文地址:https://www.cnblogs.com/xuying-fall/p/9463123.html
Copyright © 2020-2023  润新知