Loading

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 语句中使用记录类型.

 

posted @ 2018-04-08 21:37  火柴天堂  阅读(1885)  评论(0编辑  收藏  举报