练习1:
--查找scott用户的emp表中的所有数据,
--如果job为MANAGER 工资大于2500,则下调百分之10;如果小于2500 则增加百分之10,
--如果job为SALESMAN 工资小于1500 则上调百分之10;
--最后符合条件的人.插入到test表中.并且打印符合条件的人数的个数.
--Test表结构如下:
--Ename varchar
--Sal number
- --创建test表
- create table test(Ename varchar(20), Sal number);
- --存储过程
- create or replace procedure lj_pro1 is
- cursor emp_cur IS select * from emp;
- v_sql varchar2(100) := 'select count(1) from test';
- v_total number;
- begin
- FOR emp_rec IN emp_cur loop
- if emp_rec.job = 'MANAGER' then
- if emp_rec.sal > 2500 then
- update emp set emp.sal = emp.sal * 0.9
- where emp.empno = emp_rec.empno;
- insert into test values (emp_rec.ename, emp_rec.sal * 0.9);
- elsif emp_rec.sal < 2500 then
- update emp set emp.sal = emp.sal * 1.1 where emp.job = 'MANAGER';
- insert into test values (emp_rec.ename, emp_rec.sal * 1.1);
- else
- null;
- end if;
- elsif emp_rec.job = 'SALESMAN' then
- if emp_rec.sal < 1500 then
- update emp set emp.sal = emp.sal * 1.1 where emp.job = 'SALESMAN';
- insert into test values (emp_rec.ename, emp_rec.sal * 1.1);
- else
- null;
- end if;
- else
- null;
- end if;
- end loop;
- execute immediate v_sql into v_total;
- dbms_output.put_line('符合条件的人数为:'||v_total);
- end;
练习2:
--建立函数valid_empno_f,根据输入的员工编号,检查员工是否存在,
--如果员工存在,则返回ture.否则返回false.
- create or replace function valid_empno_f(No number) return boolean is
- v_ename emp.ename%type;
- begin
- select ename into v_ename from emp where empno = No;
- --dbms_output.put_line('v_ename='||v_ename);
- return true;
- exception
- when no_data_found then
- --dbms_output.put_line('员工不存在!');
- return false;
- end;
练习3:
根据主管编号查询出其直接下级员工和所有下级员工、所在部门的平均薪酬、所在部门高于平均薪酬的员工(入参为主管编号,出参为分别输出下级员工集合、所有下级员工集合、部门平均薪酬、高薪员工)。
- create or replace package p_lj is
- procedure lj_pro2(mgr_in in number,
- ename_out out varchar2,
- ename_all_out out varchar2,
- avg_saL_out out number,
- high_sal_out out varchar2);
- end p_lj;
- /
- create or replace package body p_lj is
- procedure lj_pro2(mgr_in in number,
- ename_out out varchar2,
- ename_all_out out varchar2,
- avg_saL_out out number,
- high_sal_out out varchar2) is
- --定义直接下级员工游标
- cursor emp_cur is
- select * from emp where mgr = mgr_in;
- --定义下下级员工游标
- cursor emp_all_cur is
- select * from emp
- where mgr in (select empno from emp where mgr = mgr_in);
- --定义高薪员工游标
- cursor emp_high_sal_cur is
- select * from emp
- where sal >
- (select AVG(sal) from emp
- where deptno = (select deptno from emp where empno = mgr_in));
- --定义记录
- TYPE TYP_REC_EMP IS RECORD(
- empno EMP.empno%TYPE, --个人编号
- ename EMP.ename%TYPE, --姓名
- job EMP.job%TYPE, --工作岗位
- mgr EMP.mgr%TYPE, --主管编号
- hiredate EMP.hiredate%TYPE, --雇佣日期
- sal EMP.sal%TYPE, --工资
- comm EMP.comm%TYPE, --津贴
- deptno EMP.deptno%TYPE --部门编号
- );
- -- 定义记录变量
- emp_rec TYP_REC_EMP;
- --定义数组
- --TYPE TYP_TAB_EMP IS TABLE OF TYP_REC_EMP INDEX BY VARCHAR2(30);
- -- 定义数组变量
- --emp_tab TYP_TAB_EMP;
- --sql变量
- v_sql varchar2(1000) := 'select AVG(sal) from emp where deptno =(select deptno from emp where empno =' ||
- mgr_in || ')';
- --记录异常编号和信息
- err_num NUMBER;
- err_msg VARCHAR2(100);
- begin
- -- 查询直接下级员工
- ename_out := '直接下级员工的姓名:';
- FOR emp_rec IN emp_cur loop
- ename_out := ename_out || emp_rec.ename || ', ';
- end loop;
- -- 查询所有下级员工
- ename_all_out := '所有下级员工的姓名:';
- ename_all_out := ename_out;
- FOR emp_rec IN emp_all_cur loop
- ename_all_out := ename_all_out || emp_rec.ename || ', ';
- end loop;
- --查询主管所在部门的平均薪酬
- execute immediate v_sql
- into avg_saL_out;
- --查询高薪员工
- high_sal_out := '高薪员工的姓名:';
- FOR emp_rec IN emp_high_sal_cur loop
- high_sal_out := high_sal_out || emp_rec.ename || ', ';
- end loop;
- --异常处理
- exception
- when no_data_found then
- err_num := SQLCODE;
- err_msg := SQLERRM;
- dbms_output.put_line('数据库中没有编号为'||mgr_in||'的主管');
- insert into log values(err_num,'procedure lj_pro2',err_msg);
- commit;
- when too_many_rows then
- err_num := SQLCODE;
- err_msg := SQLERRM;
- dbms_output.put_line('返回了多行!请使用游标!');
- insert into log values(err_num,'procedure lj_pro2',err_msg);
- commit;
- when cursor_already_open then
- err_num := SQLCODE;
- err_msg := SQLERRM;
- dbms_output.put_line('游标已经打开!');
- insert into log values(err_num,'procedure lj_pro2',err_msg);
- commit;
- when invalid_cursor then
- err_num := SQLCODE;
- err_msg := SQLERRM;
- dbms_output.put_line('请检测游标是否打开!');
- insert into log values(err_num,'procedure lj_pro2',err_msg);
- commit;
- when invalid_number then
- err_num := SQLCODE;
- err_msg := SQLERRM;
- dbms_output.put_line('输入的数字不正确!');
- insert into log values(err_num,'procedure lj_pro2',err_msg);
- commit;
- when OTHERS then
- err_num := SQLCODE;
- err_msg := SQLERRM;
- dbms_output.put_line(err_num||'---'||err_msg);
- insert into log values(err_num,'procedure lj_pro2',err_msg);
- commit;
- end lj_pro2;
- begin
- null;
- end p_lj;
- /