包
一、包的概述
- 简单来说就是对pl/sql 程序的包装(相关过程、函数变量和游标等)
- 包与类相同,包中程序元素分为公用和私用两种本质区别就是访问范围有所区别
公有元素:都可以访问
私有元素:只能被包中的过程和或者函数访问 - 可以模块化编程,还可以封装,对外隐藏包内信息,首次访问时,会将整个包加入内存,再次访问时内存中读取,从而提高执行效率
二、包的实现
- 包定义:声明包内数据的类型、变量、游标、子程序和异错误处理等元素,这些都是共有元素
- 包主体:包定义的具体实现,它定义了包定义部分所有声明的游标和子程序,在包体中还可以声明私有元素
- 包定义和包主体分开编译,并作为两部分公开的对象存储在数据字典中
(1)我们能使用create package命令创建包
基本语法:
--创建包
--基本语法
CREATE [OR REPLACE] PACKAGE PACKAGE_NAME
IS|AS
[共有数据类型定义]
[共有的游标定义]
[共有的变量常量声明]
[共有过程,函数声明]
EMD PACKAGE_ANME;
(2)**创建包体使用create package body **
基本语法:
--基本语法
CREATE OR REPLACE PACKAGE BODY PACKAGE_NAME
IS|AS
[私有数据类型定义]
[私有变量和和常量声明]
[私有过程、函数声明]
[公有游标定义]
[公有过程、函数]
BEGIN
PL/SQL语句;
END;
END;
(3)包的删除操作
DROP PACKAGE NAME;--后删除包头
DROP PACKAGE BODY NAME; --先删包体
代码实现:
--创建package
CREATE OR REPLACE PACKAGE MY_PACKAGE
IS
V_NUM CONSTANT NUMBER:=100;
PROCEDURE PARAM_PROC(V_DEPTNO IN EMP.DEPTNO%TYPE,V_SUM OUT EMP.SAL%TYPE);
FUNCTION PARAM_FUN(V_DEPTNO IN EMP.DEPTNO%TYPE DEFAULT 22)
RETURN NUMBER;
END MY_PACKAGE;
--创建包体 package body
CREATE OR REPLACE PACKAGE BODY MY_PACKAGE
IS
PROCEDURE PARAM_PROC(V_DEPTNO IN EMP.DEPTNO%TYPE,V_SUM OUT EMP.SAL%TYPE)
IS
--定义游标
CURSOR sal_cursor IS SELECT sal FROM emp WHERE DEPTNO=V_DEPTNO;
V_SAL EMP.SAL%TYPE;
BEGIN
V_SUM:=0;
OPEN SAL_CURSOR;
LOOP
FETCH SAL_CURSOR INTO V_SAL;
EXIT WHEN SAL_CURSOR%NOTFOUND;
V_SUM:= V_SUM+V_SAL;
END LOOP;
CLOSE SAL_CURSOR;
END;
FUNCTION PARAM_FUN(V_DEPTNO IN EMP.DEPTNO%TYPE DEFAULT 22)
RETURN NUMBER
IS
--定义游标
CURSOR SAL_CURSOR IS SELECT SAL FROM EMP WHERE DEPTNO=V_DEPTNO;
V_SAL EMP.SAL%TYPE;
V_SUM NUMBER :=0;
BEGIN
OPEN SAL_CURSOR;
LOOP
FETCH SAL_CURSOR INTO V_SAL;
EXIT WHEN SAL_CURSOR%NOTFOUND;
V_SUM:=V_SUM+V_SAL;
END LOOP;
CLOSE SAL_CURSOR;
RETURN V_SUM;
END;
END MY_PACKAGE;
--访问包中成员:格式:包名.成员
BEGIN
DBMS_OUTPUT.PUT_LINE(MY_PACKAGE.V_NUM);
END;
DECLARE
V_RESULT NUMBER ;
BEGIN
MY_PACKAGE.PARAM_PROC(10,V_RESULT);
DBMS_OUTPUT.PUT_LINE(V_RESULT);
END;
SELECT MY_PACKAGE.PARAM_FUN(10) FROM DUAL;
注意:
- 包体中要实现函数或过程,应当在包规范中声明;
- 在调用包中的某个函数或过程的时候,需要使用对应的方法
- 必须以 :包名.成员 方法实现
过程调用:
包名.过程名/(参数…)
函数的调用:
select 包名.函数名(参数…)from dual;
在包体中对函数和过程的实现不能使用create
编写程序遇见的bug:
主要原因:包头中变量名和包体中的变量名称不一致导致,要仔细检查拼写