zoukankan      html  css  js  c++  java
  • 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%原创!且读且学习。
  • 相关阅读:
    Java+7入门经典 -1 简介
    优化算法动画演示Alec Radford's animations for optimization algorithms
    如何写科技论文How to write a technical paper
    开始学习深度学习和循环神经网络Some starting points for deep learning and RNNs
    用500行Julia代码开始深度学习之旅 Beginning deep learning with 500 lines of Julia
    用10张图来看机器学习Machine learning in 10 pictures
    ICLR 2013 International Conference on Learning Representations深度学习论文papers
    ICLR 2014 International Conference on Learning Representations深度学习论文papers
    卷积神经网络CNN(Convolutional Neural Networks)没有原理只有实现
    卷积神经网络Convolutional Neural Networks
  • 原文地址:https://www.cnblogs.com/xuying-fall/p/9463123.html
Copyright © 2011-2022 走看看