黑马程序员技术交流社区
标题:
PL/SQL编程之函数与触发器
[打印本页]
作者:
黄文伯
时间:
2013-5-23 22:55
标题:
PL/SQL编程之函数与触发器
本帖最后由 黄文伯 于 2013-5-24 20:00 编辑
数据源
表emp:
create table emp(
empno number(4),
ename varchar2(10),
sal number(7,2),
deptno number(3));
insert into emp values(7369,'SMITH',800,20);
insert into emp values(7499,'ALLEN',1600,30);
insert into emp values(7521,'WARD',1250,30);
insert into emp values(7566,'JONES',2975,20);
insert into emp values(7654,'MARTIN',1250,30);
insert into emp values(7698,'BLAKE',2850,30);
insert into emp values(7782,'CLARK',2450,10);
insert into emp values(7788,'SCOTT',3000,20);
insert into emp values(7839,'KING',5000,10);
insert into emp values(7844,'TURNER',1500,30);
insert into emp values(7876,'ADAMS',1100,20);
insert into emp values(7900,'JAMES',950,30);
insert into emp values(7902,'FORD',3000,20);
insert into emp values(7934,'MILLER',1300,10);
复制代码
表dept:
drop table dept;
create table dept(
deptno number(3),
dname varchar2(14),
loc varchar2(13),
totalPerson int);
insert into dept values(10,'accounting','new york',0);
insert into dept values(20,'research','dallas',0);
insert into dept values(30,'sales','chicago',0);
insert into dept values(40,'operations','boston',0);
复制代码
1.包
创建包emp_pkg,实现以下功能:
过程hireEmp,即新增一个员工,参数自行定义
过程fireEmp,即删除一个员工,参数自行定义
函数getSal,即根据员工编号获取其工资,并进行no_data_found的异常处理
调用该包的过程和函数,并查看结果是否正确
新增一员工,数据为:9999,'tiger',1700,40
获取员工编号为7654和8000的工资
删除编号为9999的员工
删除该包
2.触发器
删除emp中所有记录
创建触发器empdepTrg,实现下面的功能:
当新增员工时,其对应的部门人数需 +1;
当删除员工时,其对应的部门人数需 -1;
当修改员工部门时,原部门人数需 -1,新部门人数需 +1
用下列数据进行测试,查看dept表的totalPerson数据是否正确
insert into emp values(7369,'SMITH',800,20);
insert into emp values(7499,'ALLEN',1600,30);
insert into emp values(7521,'WARD',1250,30);
insert into emp values(7698,'BLAKE',2850,30);
insert into emp values(7782,'CLARK',2450,10);
insert into emp values(7788,'SCOTT',3000,20);
insert into emp values(7839,'KING',5000,10);
insert into emp values(7844,'TURNER',1500,30);
insert into emp values(7876,'ADAMS',1100,20);
复制代码
增加下列数据后,请记住dept表的totalPerson数据
insert into emp values(9999,'tiger',1700,40);
复制代码
将员工编号9999的部门编号改为30后,再查看dept表的totalPerson数据有何变化
作者:
袁梦希
时间:
2013-5-23 23:22
我表示技术很高深,另请大神吧{:soso_e163:}
作者:
袁梦希
时间:
2013-5-23 23:24
这种问题可以去javaEE交流专区,这里的的提问都是一些基础性的东西{:soso_e100:}
作者:
黄文伯
时间:
2013-5-24 09:18
袁梦希 发表于 2013-5-23 23:24
这种问题可以去javaEE交流专区,这里的的提问都是一些基础性的东西 ...
好的,谢谢斑竹提醒
作者:
黄文伯
时间:
2013-5-24 12:20
老方常说细节决定程序员的高度,PL/SQL中ELSEIF应该写成'ELSIF',参考代码如下所示:
--建立包说明部分
CREATE OR REPLACE PACKAGE emp_pkg IS
--hireEmp存储过程
PROCEDURE hireEmp
(p_empno IN emp.empno%TYPE,
p_ename IN emp.ename%TYPE,
p_sal IN emp.sal%TYPE,
p_deptno IN emp.deptno%TYPE);
--fireEmp存储过程
PROCEDURE fireEmp
(p_empno IN emp.empno%TYPE);
--getSal函数
FUNCTION getSal(p_empno IN NUMBER) RETURN NUMBER;
END emp_pkg;
/
--建立包主体
CREATE OR REPLACE PACKAGE BODY emp_pkg
IS
--hireEmp存储过程
PROCEDURE hireEmp
(p_empno IN emp.empno%TYPE,
p_ename IN emp.ename%TYPE,
p_sal IN emp.sal%TYPE,
p_deptno IN emp.deptno%TYPE)
IS
BEGIN
INSERT INTO emp(empno,ename,sal,deptno) VALUES(p_empno,p_ename,p_sal,p_deptno);
COMMIT;
END hireEmp;
--fireEmp存储过程
PROCEDURE fireEmp
(p_empno IN emp.empno%TYPE)
IS
BEGIN
DELETE FROM emp WHERE empno = p_empno;
COMMIT;
END fireEmp;
--getSal函数
FUNCTION getSal(p_empno IN NUMBER) RETURN NUMBER
IS
v_sal NUMBER;
BEGIN
SELECT sal INTO v_sal FROM emp WHERE empno = p_empno;
return(v_sal);
--异常处理
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR('-20091','不存在这个编号的雇员');
END getSal;
END emp_pkg;
/
--调用hireEmp存储过程
EXECUTE emp_pkg.hireEmp(9999,'tiger',1700,40);
SELECT * FROM emp;
--调用getSal函数
SELECT emp_pkg.getSal(7654) FROM dual;
SELECT emp_pkg.getSal(8000) FROM dual;
--调用fireEmp存储过程
EXECUTE emp_pkg.fireEmp(9999);
SELECT * FROM emp;
--删除包主体
DROP PACKAGE BODY emp_pkg;
--删除包
DROP PACKAGE emp_pkg;
复制代码
--删除emp中所有记录
DELETE FROM emp;
--创建触发器empdepTrg
CREATE OR REPLACE TRIGGER emp_dep_Trg
AFTER INSERT OR UPDATE OR DELETE ON emp
REFERENCING OLD AS old NEW AS new
FOR EACH ROW
BEGIN
--当新增员工时,其对应的部门人数需 +1
IF INSERTING THEN
UPDATE dept
SET totalPerson = totalPerson + 1
WHERE deptno = :new.deptno;
--当删除员工时,其对应的部门人数需 -1;
ELSIF DELETING THEN
UPDATE dept
SET totalPerson = totalPerson - 1
WHERE deptno = :old.deptno;
--当修改员工部门时,原部门人数需 -1,新部门人数需 +1
ELSIF UPDATING('deptno') THEN
UPDATE dept
SET totalPerson = totalPerson - 1
WHERE deptno = :old.deptno;
UPDATE dept
SET totalPerson = totalPerson + 1
WHERE deptno = :new.deptno;
END IF;
END;
/
测试:
SELECT * FROM dept;
update emp
set deptno=30
where empno=9999;
delete from emp where empno=9999;
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2