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
















