在大型的项目中 会有很多的模块 每个模块有自己的存过函数等
放在一起很难维护 为了方便管理 吧相同模块放在同一个包中
┌包定义 PACKAGE
└包主体 PACKAGE BODY
–创建包定义的语法
CREATE OR REPLACE PACKAGE pak_name IS|AS
FUNCTION fun_1 … RETURN …;
FUNCTION fun_2 … RETURN …;
…
PROCEDURE pro_1 … ;
PROCEDURE pro_2 … ;
…
TYPE …
CURSOR …
v1 …
…
END pak_name;
–创建包主体的语法
CREATE OR REPLACE PACKAGE BODY pak_name IS|AS
FUNCTION fun_1 … RETURN … IS|AS
[声明]
BEGIN
…
RETURN …
END;
FUNCTION fun_2 … RETURN … IS|AS
展开
…
PROCEDURE pro_1 … IS|AS
展开
PROCEDURE pro_2 … IS|AS
展开
…
END pak_name;
包定义
包定义声明了数据类型/变量/常量/游标/子程序/异常处理等…包主体
包主体是包定义的具体实现,它定义了包定义部分所声明的游标和子程序.
全局变量和本地变量
查看所有的有名块 SELECT * FROM user_source;
--创建一个包,包含fun1,pro1,pro2
--fun1 函数 输入一个员工编号,返回部门名称
SELECT pkg_3.fun1(7788) FROM dual;
--pro1 存过 输入一个员工编号,输出部门平均工资和人数
DECLARE v1 NUMBER;v2 NUMBER; BEGIN pkg_3.pro1(7788,v1,v2);END;
--pro2 存过 输入一个姓名,打印他的名字和他经理的名字
CALL pkg_3.pro2('JONES');
CREATE OR REPLACE PACKAGE pkg_3 IS
FUNCTION fun1(v_empno NUMBER) RETURN VARCHAR2;
PROCEDURE pro1(v_empno NUMBER,v_avg_sal OUT NUMBER,v_cnt OUT NUMBER);
PROCEDURE pro2(v_ename VARCHAR2);
END pkg_3;
CREATE OR REPLACE PACKAGE BODY pkg_3 IS
--fun1 函数 输入一个员工编号,返回部门名称
FUNCTION fun1(v_empno NUMBER) RETURN VARCHAR2 IS
v_dname VARCHAR2(20);
BEGIN
SELECT dname INTO v_dname FROM dept
WHERE deptno=(SELECT deptno FROM emp WHERE empno=v_empno);
RETURN v_dname;
END;
--pro1 存过 输入一个员工编号,输出部门平均工资和人数
PROCEDURE pro1(v_empno NUMBER,v_avg_sal OUT NUMBER,v_cnt OUT NUMBER) IS
BEGIN
SELECT AVG(sal),COUNT(1) INTO v_avg_sal,v_cnt FROM emp
WHERE deptno=(SELECT deptno FROM emp WHERE empno=v_empno);
dbms_output.put_line(v_avg_sal||' '||v_cnt);
END;
--pro2 存过 输入一个姓名,打印他的名字和他经理的名字
PROCEDURE pro2(v_ename VARCHAR2) IS
v_mname VARCHAR2(20);
BEGIN
SELECT b.ename INTO v_mname FROM emp a,emp b
WHERE a.mgr=b.empno(+) AND a.ename=v_ename;
dbms_output.put_line(v_ename||' '||v_mname);
END;
END pkg_3;
--创建一个包,包含3个函数,1个存过
--f1 函数 输入一个员工编号 number 返回员工工资
SELECT pak_4.f1(7788) FROM dual;
--f1 函数 输入一个员工姓名 varchar2 返回部门名称
SELECT pak_4.f1('SCOTT') FROM dual;
--f1 函数 输入一个日期 date 返回这个日期之前入职的人数
SELECT pak_4.f1(SYSDATE) FROM dual;
--f1 存过 把dept表10部门的部门所在地插入到emp_1的job列
CALL pak_4.f1();
SELECT * FROM emp_1;
CREATE OR REPLACE PACKAGE pak_4 IS
FUNCTION f1(v_empno NUMBER) RETURN NUMBER;
FUNCTION f1(v_ename VARCHAR2) RETURN VARCHAR2;
FUNCTION f1(v_date DATE) RETURN NUMBER;
PROCEDURE f1;
END pak_4;
CREATE OR REPLACE PACKAGE BODY pak_4 IS
--f1 函数 输入一个员工编号 number 返回员工工资
FUNCTION f1(v_empno NUMBER) RETURN NUMBER IS
v_sal NUMBER;
BEGIN
SELECT sal INTO v_sal FROM emp WHERE empno=v_empno;
RETURN v_sal;
END;
--f1 函数 输入一个员工姓名 varchar2 返回部门名称
FUNCTION f1(v_ename VARCHAR2) RETURN VARCHAR2 IS
v_dname VARCHAR2(20);
BEGIN
SELECT dname INTO v_dname FROM dept
WHERE deptno=(SELECT deptno FROM emp WHERE ename=v_ename);
RETURN v_dname;
END;
--f1 函数 输入一个日期 date 返回这个日期之前入职的人数
FUNCTION f1(v_date DATE) RETURN NUMBER IS
v_cnt NUMBER;
BEGIN
SELECT count(1) INTO v_cnt FROM emp WHERE hiredate<v_date;
RETURN v_cnt;
END;
--f1 存过 把dept表10部门的部门所在地插入到emp_1的job列
PROCEDURE f1 IS
BEGIN
INSERT INTO emp_1(job) SELECT loc FROM dept WHERE deptno=10;
END;
END pak_4;
--包的重载
包的子程序的名字相同但是通过传入不同的参数类型/参数个数,得到不同的结果