delcare
--声明一个变量,这个变量用来接收游标返回的结果集。
v_salary auths.salary%type;
v_code auths.author_code%type;
/*声明游标,该游标的查询结果集是作家代码为"A00001"到"A00006"的工资值。*/
cursor c_salary is select salary,author_code from auths where author_code<='A00006';
begin
--打开游标,并初始化结果集
open c_salary;
loop
--推进游标,将游标的查询结果集中的一行存到变量v_salary中。
fetch c_salary into v_salary,v_code;
--当结果集中没有行时退出循环。
exit when c_salary%notfound;
--如果查询到的作家工资小于或等于200,则增加该作家的工资值。
if v_salary<=200 then
update auths set salary=salary+50 where author_code=v_code;
end if;
end loop;
--关闭游标,释放游标占用资源。
close c_salary;
--提交所做的修改。
commit;
end;
PL/SQL还提供了一种简单类型的循环,可以自动控制游标的打开、推进和关闭,叫做游标的FOR循环。
delcare
cursor c_salary is
select salary form auths where author_code<='A00006';
begin
--开始游标FOR循环,隐含地打开c_salary游标。
for v_salary in c_salary loop
--一个隐含的fetch语句在这里被执行。
if v_salary.salary<=200 then
update auths set salary=salary+50 where salary=v_salary.salary;
end if;
--在循环继续前,一个隐含的c_auths%notfound被检测。
end loop;
--现在循环已经结束,c_auths游标的一个隐含的close操作被执行。
commit;
end;
使用current of cursor子句作为条件
delcare
--声明游标时在select语句中必须加for update of子句。
cursor c_salary is
select salary form auths where author_code<'A00006' for update of salary;
begin
for v_salary in c_salary loop
if v_salary.salary<=200 then
--下面的update语句中的current of子句用来表明结果集的当前行。
update auths set salary=salary+50 where current of c_salary;
end if;
end loop;
commit;
end;
begin
--在下面的FOR循环中隐含地声明了一个游标c_salary。
for c_salary in
(select salary form auths where author_code<='A00006') loop
if c_salary.salary<=200 then
update auths set salary=salary+50 where salary=c_salary.salary;
end if;
end loop;
commit;
end;
begin
update auths set entry_date_time=sysdate where author_code='A00017';
--如果update语句中修改的行不存在(SQL%notfound返回值为true),则向auths表中插入一行。
if sql%nofound then
insert into auths(author_code,name,sex,birthdate,salary,entry_date_time)
values('A000017','qiuys',1,'30-apr-40',88.5,sysdate);
end if;
end;
--如果update语句中修改的行不存在(sql%rowcount=0)
declare
v_birthdate date;
begin
select birthdate into v_birthdate from auths where name='qiuys';
--如果查询到一条记录,则删除该记录。
if sql%found then
delete from auths where name='qiuys';
end if;
exception
when no_data_found then
dbms_output.put_line('该记录不存在');
when too_many_rows then
dbms_output_line('存在同名的作家');
end;
open cursor_variable for select_statement;
declare
type t_authorsref is ref cursor return auths%rowtype;
v_authscv t_authorsref;
--然后打开
open v_authscv for select * from auths;
set serveroutput on size 100000 --设置存储缓冲区大小。
declare
/*定义游标变更类型t_curref,该游标变量类型没有指定结果集类型,所以该游标变量类型的变量可以返回不同的PL/SQL记录类型。*/
type t_curref is ref cursor;
--声明一个游标变量类型的变量
c_cursorref t_curref;
--定义PL/SQL记录类型t_authorrec,该类型的变量用来接收游标变量的返回值。
type t_authorrec is record(
authorcode auths.author_code%type,
name auths.name%type);
--定义PL/SQL记录类型t_articlerec,该类型的变量也用来接收游标变量的返回值。
type t_articlerec is record(
authorcode article.author_code%type,
title artitle.title%type);
--声明两个记录类型变量。
v_author t_authorrec;
v_article t_articlerec;
begin
--打开游标变量c_cursorref,返回t_authorrec类型的记录。
open c_cursorref for
select author_code,name from auths where author_code in('A00001','A00002','A00003','A00004','A00005');
--推进游标变量
fetch c_cursorref into v_author;
--游标变量的推进循环。
while c_cursorref%found loop
--将作家代码和相应的作家名字输出到屏幕上。
dbms_output.put(v_author.authorcode||':'||v_author.name||' ');
fetch c_cursorref into v_author;
end loop;
dbms_output.new_line;--向屏幕上输出一个回车行。
--关闭游标变量,仅仅将游标变量指定的资源释放掉,游标变量本身的存储空间没有释放掉。
close c_cursorref;
--再次打开游标变量,返回t_articlerec类型的记录。
open c_cursorref for
select author_code,title from article
where author_code in('A00001','A00002','A00003','A00004','A00005');
fetch c_cursorref into v_article;
while c_cursorref%found loop
...
end loop;
close c_cursorref;
end;