PLSQL編程

練習1:

--查找scott用戶的emp表中的所有數據,
--如果job爲MANAGER 工資大於2500,則下調百分之10;如果小於2500 則增加百分之10,
--如果job爲SALESMAN 工資小於1500 則上調百分之10;
--最後符合條件的人.插入到test表中.並且打印符合條件的人數的個數.
--Test表結構如下:
--Ename varchar
--Sal number

  1. --創建test表  
  2. create table test(Ename varchar(20), Sal number);  
  3. --存儲過程  
  4. create or replace procedure lj_pro1 is 
  5.   cursor  emp_cur IS   select * from emp;  
  6.   v_sql    varchar2(100) := 'select count(1) from test';  
  7.   v_total  number;  
  8. begin 
  9.   FOR emp_rec IN emp_cur loop  
  10.     if  emp_rec.job = 'MANAGER'  then 
  11.       if  emp_rec.sal > 2500  then 
  12.         update  emp set  emp.sal  =  emp.sal * 0.9  
  13.           where emp.empno = emp_rec.empno;  
  14.         insert  into  test  values (emp_rec.ename, emp_rec.sal * 0.9);  
  15.       elsif  emp_rec.sal < 2500  then 
  16.         update  emp  set  emp.sal  =  emp.sal * 1.1  where  emp.job = 'MANAGER';  
  17.         insert  into  test  values (emp_rec.ename, emp_rec.sal * 1.1);  
  18.       else 
  19.         null;  
  20.       end if;  
  21.     elsif  emp_rec.job = 'SALESMAN'  then 
  22.       if  emp_rec.sal < 1500  then 
  23.         update  emp  set  emp.sal  =  emp.sal * 1.1 where  emp.job = 'SALESMAN';  
  24.         insert  into  test  values (emp_rec.ename, emp_rec.sal * 1.1);  
  25.       else 
  26.         null;  
  27.       end if;  
  28.     else 
  29.       null;  
  30.     end if;  
  31.   end loop;  
  32.   execute  immediate v_sql into  v_total;  
  33.   dbms_output.put_line('符合條件的人數爲:'||v_total);  
  34. end

練習2:

--建立函數valid_empno_f,根據輸入的員工編號,檢查員工是否存在,
--如果員工存在,則返回ture.否則返回false.

  1. create  or  replace  function  valid_empno_f(No number)  return boolean  is 
  2.   v_ename  emp.ename%type;  
  3. begin 
  4.   select  ename  into  v_ename  from  emp  where  empno  =  No;  
  5.   --dbms_output.put_line('v_ename='||v_ename);  
  6.   return  true;  
  7. exception  
  8.   when  no_data_found  then 
  9.     --dbms_output.put_line('員工不存在!');  
  10.     return  false;  
  11. end

練習3:

根據主管編號查詢出其直接下級員工和所有下級員工、所在部門的平均薪酬、所在部門高於平均薪酬的員工(入參爲主管編號,出參爲分別輸出下級員工集合、所有下級員工集合、部門平均薪酬、高薪員工)。

  1. create or replace package p_lj is 
  2.   procedure lj_pro2(mgr_in         in  number,  
  3.                       ename_out      out varchar2,  
  4.                       ename_all_out  out varchar2,  
  5.                       avg_saL_out    out number,  
  6.                       high_sal_out   out varchar2);  
  7. end p_lj;  
  8. /  
  9. create or replace package body p_lj is 
  10.   procedure lj_pro2(mgr_in         in number,  
  11.                       ename_out      out varchar2,  
  12.                       ename_all_out  out varchar2,  
  13.                       avg_saL_out    out number,  
  14.                       high_sal_out   out varchar2) is 
  15.     --定義直接下級員工遊標  
  16.     cursor emp_cur is 
  17.       select * from emp where mgr = mgr_in;  
  18.     --定義下下級員工遊標  
  19.     cursor emp_all_cur is 
  20.       select *  from emp  
  21.        where mgr in (select empno from emp where mgr = mgr_in);  
  22.     --定義高薪員工遊標  
  23.     cursor emp_high_sal_cur is 
  24.       select * from emp  
  25.        where sal >  
  26.              (select AVG(sal)  from emp  
  27.                where deptno = (select deptno from emp where empno = mgr_in));  
  28.     --定義記錄  
  29.     TYPE TYP_REC_EMP IS RECORD(  
  30.       empno    EMP.empno%TYPE, --個人編號  
  31.       ename    EMP.ename%TYPE, --姓名  
  32.       job       EMP.job%TYPE, --工作崗位  
  33.       mgr       EMP.mgr%TYPE, --主管編號  
  34.       hiredate  EMP.hiredate%TYPE, --僱傭日期  
  35.       sal       EMP.sal%TYPE, --工資  
  36.       comm     EMP.comm%TYPE, --津貼  
  37.       deptno    EMP.deptno%TYPE --部門編號  
  38.       );  
  39.     -- 定義記錄變量  
  40.     emp_rec TYP_REC_EMP;  
  41.  
  42.     --定義數組  
  43.     --TYPE TYP_TAB_EMP IS TABLE OF TYP_REC_EMP INDEX BY VARCHAR2(30);  
  44.     -- 定義數組變量  
  45.     --emp_tab TYP_TAB_EMP;  
  46.  
  47.     --sql變量  
  48.     v_sql varchar2(1000) := 'select AVG(sal) from emp where deptno =(select deptno from emp where empno =' ||  
  49.                             mgr_in || ')';  
  50.     --記錄異常編號和信息  
  51.     err_num   NUMBER;  
  52.     err_msg   VARCHAR2(100);  
  53.  
  54.   begin 
  55.     -- 查詢直接下級員工  
  56.     ename_out := '直接下級員工的姓名:';  
  57.     FOR emp_rec IN emp_cur loop  
  58.       ename_out := ename_out || emp_rec.ename || ', ';  
  59.     end loop;  
  60.     -- 查詢所有下級員工  
  61.     ename_all_out := '所有下級員工的姓名:';  
  62.     ename_all_out := ename_out;  
  63.     FOR emp_rec IN emp_all_cur loop  
  64.       ename_all_out := ename_all_out || emp_rec.ename || ', ';  
  65.     end loop;  
  66.     --查詢主管所在部門的平均薪酬  
  67.     execute immediate v_sql  
  68.       into avg_saL_out;  
  69.     --查詢高薪員工  
  70.     high_sal_out := '高薪員工的姓名:';  
  71.     FOR emp_rec IN emp_high_sal_cur loop  
  72.       high_sal_out := high_sal_out || emp_rec.ename || ', ';  
  73.     end loop;    
  74.     --異常處理  
  75.   exception  
  76.     when no_data_found then   
  77.       err_num :=  SQLCODE;  
  78.       err_msg := SQLERRM;  
  79.       dbms_output.put_line('數據庫中沒有編號爲'||mgr_in||'的主管');  
  80.       insert into log values(err_num,'procedure lj_pro2',err_msg);  
  81.       commit;  
  82.     when too_many_rows then 
  83.       err_num :=  SQLCODE;  
  84.       err_msg := SQLERRM;  
  85.       dbms_output.put_line('返回了多行!請使用遊標!');  
  86.       insert into log values(err_num,'procedure lj_pro2',err_msg);  
  87.       commit;  
  88.     when cursor_already_open then 
  89.       err_num :=  SQLCODE;  
  90.       err_msg := SQLERRM;  
  91.       dbms_output.put_line('遊標已經打開!');  
  92.       insert into log values(err_num,'procedure lj_pro2',err_msg);  
  93.       commit;  
  94.     when invalid_cursor then 
  95.       err_num :=  SQLCODE;  
  96.       err_msg := SQLERRM;  
  97.       dbms_output.put_line('請檢測遊標是否打開!');  
  98.       insert into log values(err_num,'procedure lj_pro2',err_msg);  
  99.       commit;  
  100.     when invalid_number then 
  101.       err_num :=  SQLCODE;  
  102.       err_msg := SQLERRM;  
  103.       dbms_output.put_line('輸入的數字不正確!');  
  104.       insert into log values(err_num,'procedure lj_pro2',err_msg);  
  105.       commit;  
  106.     when OTHERS then 
  107.       err_num :=  SQLCODE;  
  108.       err_msg := SQLERRM;  
  109.       dbms_output.put_line(err_num||'---'||err_msg);  
  110.       insert into log values(err_num,'procedure lj_pro2',err_msg);  
  111.       commit;  
  112.   end lj_pro2;  
  113.  
  114. begin 
  115.   null;  
  116. end p_lj;  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章