创建包规范和包体:
举例:
--创建包规范
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 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(-20008,'部门号不存在');
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;
再举个栗子(个人感觉还是上代码通俗易懂):
--根据员工号查询工资,如果工资小于等于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(-20008,'此员工号不存在!');
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;
包的调用与删除
栗子:
--示例一:调用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,-20008);
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;
--示例二:调用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;
--示例三:调用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,-20008);
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;
栗子:
--用SQLPLUS命令调用(下述命令请在command窗口或SQLPLUS窗口执行)
/*
VAR v_empno NUMBER
EXEC :v_empno := &no
VAR v_salary NUMBER
EXEC :