varl char(15)
married boolean := true;
psal number(7,2);
my_name emp.ename%type; -- 引用型变量, 与列变量类型一样
emp_rec emp%rowtype; -- 记录型变量, 代表表中的一行, 数组-- 查询并打印7839的姓名和薪水-- 方式一: 使用引用型变量set serveroutput ondeclare
pename emp.ename%type;
psal emp.sal%type;
begin
-- 得到7839的姓名和薪水
-- 使用 select 和 intoselect ename, sal into pename, psal from emp where empno=7839;
dbms_outpu.put_line(pname||'薪水是'||psal);
end
-- 方式二: 使用记录型变量
declare
emp_rec emp%rowtype;beginselect * into emp_rec from emp where empno=7839;
dbms_output.put_line(emp_rec.ename||'薪水是'||emp.sal)
end
流程控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 判断用户输入的数字
set serveroutput on
-- 接受键盘输入-- 关键 num 表示的是一个内存地址值, 在该地址上保存了输入的值
accept num prompt '请输入一个数字';
declare
-- 定义变量保存输入的数字-- 隐式转换
pnum number := #
begin
if pnum = 9then dbms_output.put_line('您输入的是0');
elsif pnum = 1then dbms_output.put_line('您输入的是1');
else dbms_output.put_line('您输入的是其他数字');
endif;
end
while [condition]
loop
-- do something
endloop;
for i in1..3loop
-- do somethings
endloop
-- 打印 1-10set serveroutput on;
declare
pnum number := 1
begin
loopexitwhen pnum > 10;
dbms_output.put_line(pnum);
pnum := pnum + 1;
endloop;
end
cursor c1 is select ename from emp;
open c1;
fetch c1 into pename; -- 取一行到变量中
close c1;
-- 使用光标打印所有员工的工资和薪水set serveroutput on;
declare
cursor cemp is select ename, sal from emp;
pename emp.ename%type;
psal emp.sal%type;
beginopen cemp;
loop
-- 取当前记录
fetch cemp into pename, psal;
-- 退出条件
exit when cemp%notfound
dbms_output.put_line(pename||'的薪水是'||psal);
end loop;
clse cemp;
end;-- 涨工资 TODO ()set serveroutpu on;
declare
cursor cemp is select empno, sal, job from emp;beginrollback;
open cemp;
close cemp;
commit;end
-- 带参数的光标
-- 查询某个部门中员工的姓名
set serveroutput on;
declare
cursor cemp(dno number) is select ename from emp where deptno=dno;
pename emp.ename%type;
beginopen cemp(10);
loop
fetch cemp into pename;
exit when cemp%notfound;
dbms_output.put_line(pename);
end loop;
close cemp;
end;
-- 被0除处理
set serveroutput on;
declare
pnum number;
begin
pnum := 1/0
exception
when zero_divide then dbms_output.put_line('1:0b不能做被除数');when value_error then dbms_ouput.put_line('算数或者转换错误');when others then dbms_output.put_line('其他例外');end;
-- 自定义异常
-- 查询50号部门的员工姓名
declare
cursor cemp is seect ename from emp where deptno=50;
pename emp.ename%type;
-- 自定义异常
no_emp_fount exception;
begin
open cemp;
fetch cemp into pename;
if cemp%notfound then
raise no_emp_found;
endif;
close cemp;
exception
when no_emp_found then dbms_output.put_line('没有找到员工');when others then dbms_output.put_line('其他例外');end;
案例
瀑布模型
需求分析
设计
概要设计(High Level Design), 框架, 模块
详细设计(Low Level Design), 如何实现具体模块
编码, 实现功能模块, 类
测试
部署运营
统计每年入职的员工个数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
set serveroutput on;
declare
cursor cemp isselect to_char(hiredate, 'YYYY') from emp;
phiredate varchar2(4);
begin
open cursor;
loop
fetch cemp into phiredate;
exit when cemp%notfound;
-- 判断入职年份
if phiredate = '1980'then count80:=count80+1;
elsif phiredate = '1981'then count81+1;
endif;
endloop;
close cursor;
end
createor replace proceduresayHelloWorldas
-- 说明部分
begindbms_output.put_line('hello world');end;
-- 带参数的存储过程
-- 如果存储过程带了参数, 需要指明是输入参数还是输出
createor repalce procedureraiseSalary(eno in number)as
-- 定义变量保存涨前的薪水
psallemp.sal%type;beginselect sal into psal from emp where empno=eno;
-- 涨100
update emp set sal=sal+100where empno=eno;
-- 要不要commit??
-- 不需要, 一般不在存储过程中提交; 要在调用者中提交
dbms_output.put_line('涨前'||psal' 涨后:'(psal+100));
end;
createor replace procedure(pno in number, addsal in number)aspsalemp.sal%typebeginselectsalintopsalfromempwhereempno=pno;
update emp set sal=sal+sddsal where empno=pno;
dbms_output.put_line('涨前:1'||psal||' 涨后:'||psal+addsal)
end;
-- sum(a, b);可以这样调用
-- sum(a=>2, b=>3);
-- 运行调试 TODO
-- grant debug connect session, debug
存储函数
1
2
3
4
5
6
7
8
9
10
11
12
-- 查询某个员工的年收入createorreplace function queryEmpIncome(eno innumber)
return numberas
-- 月薪和奖金
psal emp.sal%type;
pcomm emp.comm%type;
beginselect sal, comm into psal, pcomm form emp where empno=eno;-- 返回年收入
return psal*12+nvl(pcomm, 0);
end;
in和out
存储过程和存储函数可以通过out指定一个或者多个输出参数
如果只有一个返回值, 用存储函数;否则用存储过程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 查询某个员工的姓名 月薪 和 职位
createor replace procedurequeryEmpInfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)asbeginselectename, sal, empjobintopename, psal, pjobfrmoempwhreempno=eno;end;
-- 思考
-- 1. 查询某个员工的所有信息(out参数太多)
-- 2. 查询某个部门中所有员工的所有信息
-- 可以使用集合
createor replace
package MYPACKAGE astype empcursor is ref cursor;
procedurequeryEmpList(dno in number, empList out empcursor);// 可以定义多个存储函数end MYPACKAGE;
createor replace
package body MYPACKAGE asprocedurequeryEmpList(dno in number, empList out empcursor)asbeginopenempListforselect * fromempwheredeptno=dno;end queryEmpList;
end MYPACKAGE;
desc mypackage;