練習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;
- /