Oracle专题15之包
发表于:2025-01-22 作者:千家信息网编辑
千家信息网最后更新 2025年01月22日,1、包的概述a、什么是包?包是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合。b、包的特点?它具有面向对象程序设计语言的特点,是对PL/SQL程序设计元素(过程、函数、变量等)的
千家信息网最后更新 2025年01月22日Oracle专题15之包
1、包的概述
a、什么是包?
- 包是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合。
b、包的特点?
- 它具有面向对象程序设计语言的特点,是对PL/SQL程序设计元素(过程、函数、变量等)的封装。
- 它使程序设计模块化。
c、包中的程序元素
- 包中的程序元素分为两种:公用元素(公用组件)、私用元素(私用组件)。
e、包的组成
- 一个包由两个分开的部分组成:
- 包规范(包定义):用于定义包的公用组件,包括常量、变量、游标、过程和函数等。
- 包体(包主体):用于实现包规范所定义的公用过程和函数。包体不仅可用于实现公用过程和函数,而且还可以定义包的私有组件(变量、游标、过程、函数等)。
f、简单代码示例
- 创建包规范和包体的示例代码
--创建包规范CREATE OR REPLACE PACKAGE first_packageIS 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 first_package;--创建包体CREATE OR REPLACE PACKAGE BODY first_packageIS 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 first_package;
- 调用包中的存储过程:
DECLARE v_avgsal NUMBER; v_cnt NUMBER;BEGIN first_package.query_emp(20, v_avgsal, v_cnt); DBMS_OUTPUT.put_line('平均工资:' || v_avgsal); DBMS_OUTPUT.put_line('总人数:' || v_cnt);END;
2、包的创建
a、创建包规范
- 语法格式如下:
CREATE [OR REPLACE] PACKAGE package_nameIS | AS-- 定义公用常量、变量、游标、过程、函数等END [package_name];
示例代码:
CREATE OR REPLACE PACKAGE emp_packageIS --添加员工信息的存储过程 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;
b、创建包体
- 语法格式如下:
CREATE [OR REPLACE] PACKAGE BODY package_name IS | AS--定义私有常量、变量、游标、过程和函数等--实现公用过程和函数END [package_name];
示例代码:
CREATE OR REPLACE PACKAGE BODY emp_packageIS --添加员工信息的存储过程 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;
c、包创建的过程案例代码
根据员工号查询工资,如果工资小于等于3000,工资涨500。
--创建包规范CREATE OR REPLACE PACKAGE emp_sal_pkgIS 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_pkgIS 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;
3、包的调用和删除
a、包的调用
- 对包内共有元素(公用组件)的调用格式为:包名.元素名称(组件名称)
- 例如:emp_package.del_emp_proc();
b、 包的调用示例1
调用emp_package包下添加员工信息的存储过程。(在本专题的第2节包的创建,已经在Oracle数据库中创建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;
b、包的调用示例2
- 调用emp_package包下删除员工信息的存储过程。(在本专题的第2节包的创建,已经在Oracle数据库中创建emp_package包规范和包体)
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;
c、包的调用示例3
- 调用emp_sal_pkg包下的过程和函数:(在本专题的第2节包的创建,已经在Oracle数据库中创建emp_sal_pkg包规范和包体)
1、调用根据员工号返回员工工资的函数
2、调用更新满足条件的员工工资的过程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;
d、如何在SQLPlus窗口中进行包的调用
示例1:在SQLPlus窗口中进行emp_sal_pkg包的调用,查询员工的工资信息:
SQL> VAR v_empno NUMBERSQL> EXEC :v_empno := &noPL/SQL procedure successfully completedv_empno---------1234SQL> VAR v_salary NUMBERSQL> EXEC :v_salary := emp_sal_pkg.get_sal(:v_empno)begin :v_salary := emp_sal_pkg.get_sal(:v_empno); end;ORA-20010: 此员工号不存在ORA-06512: 在 "SCOTT.EMP_SAL_PKG", line 11ORA-06512: 在 line 1v_salary---------v_empno---------1234
示例2:在SQLPlus窗口中进行emp_sal_pkg包的调用,更新员工的工资信息:(变量v_empno已经在示例1中定义)
SQL> EXEC :v_empno := &noPL/SQL procedure successfully completedv_empno---------7369SQL> EXEC :v_salary := emp_sal_pkg.get_sal(:v_empno)PL/SQL procedure successfully completedv_salary---------800v_empno---------7369SQL> EXEC emp_sal_pkg.upd_sal(:v_empno, :v_salary)PL/SQL procedure successfully completedv_empno---------7369v_salary---------800SQL> SELECT ename, sal from emp WHERE empno = 7369;ENAME SAL---------- ---------G_EASON 1300.00
- 在SQLPlus环境中,可以使用 [VAR 变量名 变量类型]命令定义变量。
e、包的删除
- 可以使用DROP PACKAGE命令对不需要的包进行删除,语法如下:
DROP PACKAGE [BODY] [user.] package_name;
4、子程序重载
a、什么是子程序重载?
- 所谓重载是指两个或者多个子程序有相同的名称,但是拥有不同的参数变量、参数顺序或者参数数据类型。
b、示例代码
示例:1、根据员工号或者员工姓名获取员工信息;2、根据员工号或者员工姓名删除员工的信息。
--创建包规范CREATE OR REPLACE PACKAGE overload_pkgIS FUNCTION get_info(eno NUMBER) RETURN emp%ROWTYPE; FUNCTION get_info(name VARCHAR) RETURN emp%ROWTYPE; PROCEDURE del_emp(eno NUMBER); PROCEDURE del_emp(name VARCHAR);END;--创建包体 CREATE OR REPLACE PACKAGE BODY overload_pkgIS FUNCTION get_info(eno NUMBER) RETURN emp%ROWTYPE IS emp_record emp%ROWTYPE; BEGIN SELECT * INTO emp_record FROM emp WHERE empno = eno; RETURN emp_record; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20020, '不存在此员工'); END; FUNCTION get_info (name VARCHAR) RETURN emp%ROWTYPE IS emp_record emp%ROWTYPE; BEGIN SELECT * INTO emp_record FROM emp WHERE ename= name; RETURN emp_record; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20020, '不存在此员工'); END; PROCEDURE del_emp(eno NUMBER) IS BEGIN DELETE FROM emp WHERE empno = eno; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20020, '不存在此员工'); END IF; END; PROCEDURE del_emp(name VARCHAR) IS BEGIN DELETE FROM emp WHERE ename = name; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20020, '不存在此员工'); END IF; END;END overload_pkg;
- overload_pkg包的调用示例:
--根据员工号查询员工信息DECLARE emp_record emp%rowtype; e_no_emp EXCEPTION; PRAGMA EXCEPTION_INIT(e_no_emp, -20020);BEGIN emp_record := overload_pkg.get_info(&no); DBMS_OUTPUT.put_line('员工号:' || emp_record.empno || ',姓名:' || emp_record.ename || ',工资:' || emp_record.sal);EXCEPTION WHEN e_no_emp THEN DBMS_OUTPUT.put_line(SQLERRM);END;
--根据员工姓名查询员工信息DECLARE emp_record emp%rowtype; e_no_emp EXCEPTION; PRAGMA EXCEPTION_INIT(e_no_emp, -20020);BEGIN emp_record := overload_pkg.get_info('&ename'); DBMS_OUTPUT.put_line('员工号:' || emp_record.empno || ',姓名:' || emp_record.ename || ',工资:' || emp_record.sal);EXCEPTION WHEN e_no_emp THEN DBMS_OUTPUT.put_line(SQLERRM);END;
--根据员工号删除员工信息DECLARE e_no_emp EXCEPTION; PRAGMA EXCEPTION_INIT(e_no_emp, -20020);BEGIN overload_pkg.del_emp(&no); COMMIT;EXCEPTION WHEN e_no_emp THEN DBMS_OUTPUT.put_line(SQLERRM); ROLLBACK;END;
--根据员工姓名删除员工信息DECLARE e_no_emp EXCEPTION; PRAGMA EXCEPTION_INIT(e_no_emp, -20020);BEGIN overload_pkg.del_emp('&ename'); COMMIT;EXCEPTION WHEN e_no_emp THEN DBMS_OUTPUT.put_line(SQLERRM); ROLLBACK;END;
员工
过程
信息
示例
函数
变量
工资
元素
公用
存储
代码
姓名
程序
组件
游标
常量
数据
程序设计
查询
设计
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库的安全性与完整性
淄川文件审批软件开发
河北有口碑的软件开发试验设备
佳能c7260安装服务器
精通pki网络安全认证技术
网络安全手抄报写字素材
中金软件开发待遇
数据库索引数据库索引
利用数据库 开发软件开发
数据库设计会出现的问题
hbase分布式数据库应用
网络安全和信息化杂志投稿
厦门市网络安全产业联盟
中兴通讯中心软件开发
mysql数据库自动编号
liunx下执行数据库脚本
福建系统软件开发服务商
ipadpro做服务器
阿里云云数据库架构
合肥无风扇工控机服务器
石家庄软件开发培训教育班
数据库SQL易错点
清除数据库所有数据
学校网络安全月宣传情况
我的世界服务器怎么魔改好
mcpe服务器破解
王者名字是单服务器不能重复吗
万方期刊数据库人文之友杂志社
ic软件开发职业规划
石家庄启康软件开发服务有限公司