是用来操作查询结果集的,相当于JDBC中的ResultSet
select * from emp;
查询emp表
cursor 游标的名称 is 查询的结果集
cursor 游标的名称 is 查询的结果集
open 游标名
fetch 从游标 当中 取一条记录
fetch 游标名 into 变量
判断游标是否取完数据
游标名:%found :
游标名%notfound
:没有找到数据
语法
close 游标名
cursor 游标的名称 is 查询的结果集
结果集(游标):所有员工
声明一个变量,用来记录一行数据 %rowtype
。
declare
-- 游标:声明vrows游标 指向emp表的表头
cursor vrows is select * from emp;
-- 声明变量,记录一行数据
vrow emp%rowtype;--存储的是emp表第一行的数据
begin
-- 1、打开游标
open vrows;
-- 2、从游标当中提取数据
-- 循环取数据
loop
fetch vrows into vrow; -- 通过游标vrows取vrow当中的数据,将vrows 当中的数据放置到vrow
exit when vrows%notfound; --当vrows游标找不到的时候退出循环
dbms_output.put_line('姓名:'|| vrow.ename || ' 工资:' || vrow.sal);
end loop;
-- 3、关闭游标
close vrows;
end;
cursor 游标的名称[(参数名 参数类型)] is 查询的结果集
游标:指定部门的所有员工
声明一个变量记录一行数据
declare
-- 声明游标
cursor vrows(dno number) is select * from emp where deptno = dno;
-- 声明变量
vrow emp%rowtype;
begin
-- 1、打开游标,指定10号部门
open vrows(10);
-- 2、循环遍历,取数据
loop
fetch vrows into vrow; -- 通过游标vrows取vrow当中的数据,将vrows 当中的数据放置到vrow
exit when vrows%notfound; --当找不到的时候退出
dbms_output.put_line('姓名:'|| vrow.ename || ' 工资:' || vrow.sal);
end loop;
-- 关闭游标
close vrows;
end;
(1)声明游标 : 游标名 游标类型 sys_refcursor
(2)打开游标:open 游标名 for 结果集
(3)从游标当中取数据
(4)关闭游标
select * from emp;
declare
-- 声明系统引用游标
vrows sys_refcursor;
-- 声明一个变量来用于记录数据
vrow emp%rowtype;--指向emp表的表头
begin
--1、打开游标
open vrows for select * from emp;
-- 2、取数据
loop
fetch vrows into vrow;--将vrows 当中的数据放置到vrow,vrow会不断循环向下走
exit when vrows%notfound;
dbms_output.put_line('姓名:'|| vrow.ename || ' 工资:' || vrow.sal);
end loop;
close vrows;
end;
for循环遍历游标:不需要声明额外变量,不需要打开游标,不需要关闭游标 if
-- 使用for循环来遍历游标
declare
-- 声明一个游标
cursor vrows is select * from emp;
begin
for vrow in vrows loop
dbms_output.put_line('姓名:'|| vrow.ename || ' 工资:' || vrow.sal || vrow.sal || '工作:' || vrow.job);
end loop;
end;
declare
-- 声明变量
begin
-- 业务逻辑 判断和循环
exception -- 捕获异常
-- 处理异常
when 异常一 then
...
when 异常二 then
...
when others then
...处理其他异常
end;
zero_divide
: 除零异常value_error
: 类型转换异常too_many_rows
: 查询出多行记录,但是赋值给了一行记录,rowtype记录一行数据的变量no_data_fount
: 没有找到数据declare
vi number;
begin
vi := 8/0;
exception
when zero_divide then
dbms_output.put_line('发生了除零异常');
when others then
dbms_output.put_line('发生了其他异常');
end;
给数字类型的变量赋值字符串,发送异常
declare
vi number;
begin
vi := 'aaa';
exception
when zero_divide then
dbms_output.put_line('发生了除零异常');
when others then
dbms_output.put_line('发生了其他异常');
end;
declare
vi number;
begin
vi := 'aaa';
exception
when zero_divide then
dbms_output.put_line('发生了除零异常');
when value_error then
dbms_output.put_line('发生了类型转换异常');
when others then
dbms_output.put_line('发生了其他异常');
end;
too_many_rows
: 查询出多行记录,但是赋值给了一行记录,rowtype记录一行数据的变量declare
vi number;
-- 记录一行变量
vrow emp%rowtype;
begin
select * into vrow from emp;
exception
when zero_divide then
dbms_output.put_line('发生了除零异常');
when value_error then
dbms_output.put_line('发生了类型转换异常');
when too_many_rows then
dbms_output.put_line('查询出多行记录,但是赋值给了一行记录,rowtype记录一行数据的变量');
when others then
dbms_output.put_line('发生了其他异常');
end;
declare
vi number;
-- 记录一行变量
vrow emp%rowtype;
begin
select * into vrow from emp where empno = 123456; -- 查询数据并赋值给vrow
exception
when zero_divide then
dbms_output.put_line('发生了除零异常');
when value_error then
dbms_output.put_line('发生了类型转换异常');
when too_many_rows then
dbms_output.put_line('查询出多行记录,但是赋值给了一行记录,rowtype记录一行数据的变量');
when others then
dbms_output.put_line('发生了其他异常' || sqlerrm);
end;
declare
vi number;
-- 记录一行变量
vrow emp%rowtype;
begin
select * into vrow from emp where empno = 123456; -- 查询数据并赋值给vrow
exception
when zero_divide then
dbms_output.put_line('发生了除零异常');
when value_error then
dbms_output.put_line('发生了类型转换异常');
when too_many_rows then
dbms_output.put_line('查询出多行记录,但是赋值给了一行记录,rowtype记录一行数据的变量');
when no_data_found then
dbms_output.put_line('没有找到数据异常');
when others then
dbms_output.put_line('发生了其他异常' || sqlerrm);
end;
异常名 exception;
rasie 异常;
a、声明一个变量 % rowtype 。
b、查询员工信息信息,保存起来。
c、判断员工信息是否为空。
d、如果是则抛出异常。
select * from emp;
-- 查询指定编号的员工,如果没有找到,则抛出自定义的异常
declare
-- 1、声明一个变量 %rowtype
vrow emp%rowtype;
-- 2、声明一个自定义的异常
no_emp exception;
begin
-- 3、查询员工信息,保存起来
select * into vrow from emp where empno = 8888;--抛出异常
if vrow.sal is null then
raise no_emp; -- 抛出自定义的异常
end if;
exception
-- 捕获异常
when no_emp then
dbms_output.put_line('输出了自定义的异常');
when others then
dbms_output.put_line('输出了其他异常'|| sqlerrm);
end;
%found % notfound
声明一个游标
声明一个变量,记录数据
从游标当中取记录,如果取到了
如果有,则不管
如果没有就抛出自定义异常
declare
-- 声明游标vrows是查询表当中的empno = 8888
cursor vrows is select * from emp where empno = 8888;
--声明记录型的变量,声明记录型,指向emp表的表头
vrow emp%rowtype;
-- 声明一个自定义异常
no_emp exception;
begin
-- 1、打开游标
open vrows;
-- 2、取数据
fetch vrows into vrow;
-- 3、判断游标是否有数据
if vrows%notfound then
raise no_emp;--raise申请这个异常
end if;
close vrows;
-- 捕获异常
exception
when no_emp then
dbms_output.put_line('发生了自定义的异常');
end;
create [or replace] procedure 存储过程的名称(参数名 in|out 参数类型)is | as
is | as
--声明部分
begin
-- 业务逻辑
end;
参数:in 员工编号
参数:in 涨多少
声明一个变量:存储涨工资前的工资
查询出当前工资是多少
打印涨薪前的工资
更新工资
打印涨薪后的工资
create or replace procedure proc_updatesal(vempno in number,vnum in number)
is
--声明变量,记录当前工资
vsal number;
begin
-- 查询当前工资
select sal into vsal from emp where empno = vempno;
--输出涨薪前的工资
dbms_output.put_line('涨薪前:' || vsal);
--更新工资
update emp set sal = vsal + vnum where empno = vempno;
--输出涨薪后的工资
dbms_ouput.put_line('涨薪后:' || (vsal+vnum));
--提交事务
commit;
end;
-- 方式1
call proc_updatesal(7788,10);
-- 方式2 用的最多的一种方式
declare
begin
proc_updatesal(7788,-100);
end;
create {
or replace} function 存储函数的名称(参数名 in|out 参数类型,参数名 in|out 参数类型)
is | as
begin
end;
(1)他们本质上没有区别。
(2)函数存在的意义是给过程调用的 存储过程里面调用存储函数
。
(3)函数可以在sql语句里面直接调用。
(4)存储过程能实现的,存储函数也能实现,存储函数能实现的,存储过程也能实现
默认就是in。
参数:员工的编号
返回:年薪
create or replace function func_getsal(vempno number) return number
is
-- 声明变量.保存年薪
vtotalsal number;
begin
select sal*12 + nvl(comm,0) into vtotalsal from emp where empno = vempno;
return vtotalsal;
end;
调用上面创建的函数,查询7788员工编号对应的员工信息
declare
vsal number;
begin
vsal := func_getsal(7788);
dbms_output.put_line(vsal);
end;
select ename,func_getsal(empno) from emp;
参数:是员工编号
输出:年薪
create or replace procedure proc_gettotalsal(vempno in number,vtotalsal out number)
is
begin
select sal*12 + nvl(comm,0) into vtotalsal from emp where empno = vempno;
end;
declare
vtotal number;--声明变量调用函数
begin
proc_gettotalsal(7788,vtotal);-- 调用函数查询年薪和工资
dbms_output.put_line('年薪:'||vtotal);输出年薪
end;