PLSQL函數,存儲過程


  1 --創建一個函數,用來根據部門編號返回調薪幅度
  2 create or replace function get_ratio_by_dept(deptno varchar2)
  3      return number is
  4      n_salaryratio number(10,2);        --調薪比率返回值變量
  5 begin
  6      case deptno 
  7          when 10  then
  8              n_salaryratio:=1.09;
  9           when 20  then
 10              n_salaryratio:=1.11;
 11            when 30 then
 12               n_salaryratio:=1.18;
 13             else
 14               n_salaryratio:=0;
 15            end case;
 16            return n_salaryratio;
 17            end;   
 18 
 19 begin
 20   dbms_output.put_line(get_ratio_by_dept(20));
 21   end;   
 22 
 23  --創建一個存儲過程,用來實現加薪,它將調用get_ratio_by_dept來獲取加薪幅度
 24 
 25  create or replace procedure raise_salary(p_empno number)
 26  as 
 27      v_deptno number(2);
 28      v_ratio number(10,2);   --存儲調薪幅度變量
 29   begin
 30     select deptno into v_deptno from emp where empno=p_empno;
 31     v_ratio:=get_ratio_by_dept(v_deptno);
 32     if v_ratio>0
 33       then 
 34         update scott.emp
 35             set sal =sal* (1+v_ratio)
 36         where empno = p_empno;
 37         end  if;
 38         dbms_output.put_line('加薪成功!');
 39   exception
 40      when no_data_found then
 41           dbms_output.put_line('沒有找到該員工的任何信息!');
 42       when others then
 43           dbms_output.put_line('調整薪資時出現了錯誤!');             
 44     end;         
 45 
 46   set serveroutput on;  
 47   exec raise_salary(7369);   
 48 
 49 --創建包頭
 50  create or replace package emp_sal_pkg as
 51  function get_ratio_by_dept(deptno varchar2) return number;
 52  procedure raise_salary(p_empno number);
 53  end emp_sal_pkg;
 54 
 55  --創建包體  
 56  create or replace package body emp_sal_pkg as
 57       function get_ratio_by_dept(deptno varchar2)
 58         return number
 59         is 
 60         n_salaryratio number(10,2);
 61         begin
 62           case deptno 
 63          when 10  then
 64              n_salaryratio:=1.09;
 65           when 20  then
 66              n_salaryratio:=1.11;
 67            when 30 then
 68               n_salaryratio:=1.18;
 69             else
 70               n_salaryratio:=1;
 71            end case;
 72            return n_salaryratio;
 73           end get_ratio_by_dept;
 74 
 75           procedure  raise_salary (p_empno number)
 76             as 
 77             v_deptno number(2);
 78             v_ratio number(10,2);
 79           begin
 80              select deptno into v_deptno from emp where empno=p_empno;
 81     v_ratio:=get_ratio_by_dept(v_deptno);
 82     if v_ratio>0
 83       then 
 84         update scott.emp
 85             set sal =sal* (1+v_ratio)
 86         where empno = p_empno;
 87         end  if;
 88         dbms_output.put_line('加薪成功!');
 89   exception
 90      when no_data_found then
 91           dbms_output.put_line('沒有找到該員工的任何信息!');
 92       when others then
 93           dbms_output.put_line('調整薪資時出現了錯誤!');        
 94             end raise_salary;
 95             end emp_sal_pkg;  
 96 --創建過程添加新員工
 97  create or replace  procedure  AddNewEmp(p_empno emp.empno%type,
 98  p_ename emp.ename%type,
 99  p_job   emp.job%type,
100  p_sal   emp.sal%type,
101  p_deptno  emp.deptno%type:=20)
102  as
103  begin
104    if p_empno<0 then
105      raise_application_error(-20001,'員工編號必須大於0');
106      end if;
107        insert into emp
108            (empno,ename,job,sal,deptno)
109            values (p_empno,p_ename,p_job,p_sal,p_deptno);   
110    end AddNewEmp;          
111 
112 begin
113     AddNewEmp(8236,'諸葛亮','策划人員',25000,40);
114     end;
115 
116 
117 
118 子程序創建高度可維護,重用的代碼
119 (1)模塊化代碼(2)簡化應用程序(3)提升管理性:需求變更,只要改子程序
120 (4)可重用性,提高性能
121 程序調試
122 C+R  直接運行  C+N單擊進入  C+O單步逃過 C+T單步退出
123 --在過程中使用return語句
124 create or replace procedure RaiseSalary(
125        p_empno emp.empno%type) as
126        v_job emp.job%type;
127        v_sal emp.sal%type;
128 begin
129     select job,sal into v_job,v_sal from emp
130     where empno=p_empno;
131     if v_job<>'CLERK' then
132        return;               --如果不是職員則退出
133      elsif v_sal>3000 then
134        return ;
135      else
136        --否則更新薪資記錄
137       update emp set sal=Round(sal*1.12,2)  where
138         empno=p_empno;
139       end if;
140   exception
141      when no_data_found then
142       dbms_output.put_line('沒有找到員工記錄');         
143 end RaiseSalary;
144 begin
145   RaiseSalary(7369);
146   end;
147  select * from emp where empno=7369; 
148 --查詢當前scott方案下的過程和函數列表
149 select object_name,object_type,created,
150 last_ddl_time,status,temporary
151        from user_objects
152        where object_type in ('PROCEDURE','FUNCTION','TABLE');
153 
154 
155 --in  out 模式參數
156 create or replace procedure calcRaiseSalary(
157        p_job in varchar2,
158        p_salary in out number
159 )    as  
160  v_sal number(10,2); 
161  v_job varchar2(10);
162 begin
163   if p_job='CLERK' then
164     v_sal:=p_salary*1.12;
165 
166    elsif p_job='銷售人員' then
167      v_sal:=p_salary*1.18;
168    elsif p_job='經理' then
169      v_sal:=p_salary*1.19;
170    else
171      v_sal:=p_salary;
172 
173    end if;
174        p_salary:=v_sal;  ---值傳遞
175 
176     end calcRaiseSalary;       
177 
178  declare
179     v_sal number(10,2);
180     v_job varchar2(10);
181  begin
182     select sal,job into v_sal,v_job from emp where
183     empno=7369;
184     calcRaiseSalary(v_job,v_sal);
185     dbms_output.put_line('計算后的調整薪水為:'||v_sal);  --||'JOB'||v_jo
186     end;
187 
188  select * from emp where empno=7369; 
189 
190  引用傳遞:將實際參數的指針(內存地址)傳遞給形式參數,
191  值傳遞:將實際參數的值賦給形式參數,值拷貝,指向不同的內存地址
192 
193  如果參數是大型數據結構,比如集合,記錄和對象實例, 參數復制會大大降低執行速度,
194  消耗內存
195 nocopy 使得out和in out模式的參數按引用進行傳遞
196 
197 
198 
199 
200 
201 
202    --編譯包規范
203   alter package emp_pkg_overloading  compile specification;
204   --編譯包體
205   alter package emp_pkg_overloading compile body;   
206   --同時編譯包規范和包體
207   alter package emp_pkg_overloading compile package;
208 
209   --查詢包規范和包體信息
210   select object_name,object_type,created,last_ddl_time from user_objects
211   where object_type in ('PACKAGE','PACKAGE BODY');
212 
213   --查看包的源代碼
214   select line,text from user_source where name='EMP_MGMT_PKG_OVERLOADING'
215   and type='PACKAGE';
216 
217 
218   --使用returning into 為記錄變量賦值
219   declare
220     type t_emp is record(
221          empno emp.empno%type,
222          ename emp.ename%type,
223          sal emp.sal%type
224     );
225     emp_info t_emp;
226     old_sal emp.sal%type;
227    begin
228      select sal into old_sal
229        from emp
230        where empno=7369;
231        update emp
232        set sal=sal*1.1
233        where empno=7369
234        returning  empno,ename,sal into emp_info;
235       dbms_output.put_line(
236         emp_info.empno||'  '||emp_info.ename ||' '||
237         old_sal||' '|| emp_info.sal);
238 
239      end; 
240 select sal,ename from emp where empno =7369    
241 
242    --在insert語句中使用記錄類型
243    declare
244      type t_dept_rec is record(
245           rec_deptno number,
246           rec_dname varchar2(14),
247           rec_loc varchar2(13)
248      );
249      rec_dept_1 t_dept_rec;
250      rec_dept_2 dept%rowtype;
251    begin
252       rec_dept_1.rec_deptno:=71;
253       rec_dept_1.rec_dname:='系統部';
254       rec_dept_1.rec_loc:='上海';
255       insert into dept values rec_dept_1; 
256       rec_dept_2.deptno:=72;
257       rec_dept_2.dname:='開發部';
258       rec_dept_2.loc:='重慶';
259       insert into dept values rec_dept_2;
260   end;     
261 
262   select * from dept
263 
264 
265 --在update語句中使用記錄類型
266 declare
267   rec_dept_2 dept%rowtype;
268 begin
269   rec_dept_2.deptno:=20;
270   rec_dept_2.dname:='系統部';
271   rec_dept_2.loc:='上海';
272   update dept set row=rec_dept_2 where deptno=rec_dept_2.deptno;
273   end;  
274 
275     使用記錄類型的限制
276  (1)記錄類型不能出現在select語句的選擇列表, where子句,group by 子句
277  或order by子句中
278  (2)update語句中Row關鍵字只能出現在set語句之后,並且不能和子查詢連用
279  (3)不能包含其他的變量和值,不能具有嵌套的記錄類型,不支持在
280  execute immediate 語句中使用記錄類型.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM