--goto 顺序控制
declare
v_i number(4);
begin
v_i:=1;
loop
--判断是否等于0,直接用=,不需要用==
if(mod(v_i,2)=0) then
goto test_1;
end if;
dbms_output.put_line('v_i='||v_i);
--标识 后面不加;
<<test_1>>
v_i:=v_i+1;
exit when v_i>50;
end loop;
end;
--显示游标
select * from stu where gid=2;
declare
--定义一个游标
cursor c_stu is select * from stu where gid=2;
v_temp stu%rowtype;
begin
--打开游标
open c_stu;
--取值
loop
--提取游标 每提取一行给v_temp
fetch when c_stu%notfound;
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage);
end loop;
--关闭游标
close c_stu;
end;
--for 游标
declare
--定义一个游标 c_stu
cursor c_stu is select * from stu where gid=1;
begin
--for 做了打开游标,关闭游标,提取游标
for v_temp in c_stu loop
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage);
end loop;
end;
--带参数的游标
declare
--声明一个带参数的游标
cursor c_stu(v_gid stu.gid%type) is select * from stu where gid=v_gid;
v_id stu.gid%type;
v_temp stu%rowtype;
begin
v_id:='&请输入年级编号';
--打开游标
open c_stu(v_id);
loop
--提取游标
fetch c_stu into v_temp;
exit when c_stu%notfound;
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage);
end loop;
--关闭游标
close c_stu;
end;
--v_gid 带参数的游标 不需要指定范围类型
declare
cursor c_stu(v_gid number) is select * from stu where gid=v_gid;
v_id stu.gid%type;
begin
v_id:='&请输入年级编号';
for v_temp in c_stu(v_id) loop
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage);
end loop;
end;
--用游标进行批量修改
/*
大于30岁以上的,进行批量修改
子查询 业务比较复杂的情况,可以用游标解决
*/
declare
cursor c_stu2(v_sage stu2.sage%type) is select * from stu2 where sage>v_sage;
v_age stu2.sage%type;
begin
v_age := '&请输入年龄';
for v_t in c_stu2(v_age) loop
update stu2 set sname='鲁直伸' where sid=v_t.sid;
end loop;
commit;
end;
--批量修改方式2:
declare
cursor c_stu2(v_sage stu2.sage%type) is select * from stu2 where sage>v_sage for update;
v_age stu2.sage%type;
begin
v_age := '&请输入年龄';
for v_t in c_stu2(v_age) loop
update stu2 set sname='大鲁' where current of c_stu2;
end loop;
commit;
end;
--多表情况下,用游标取值(sid,sname,sage,gname)
select * from stu a,grade b where a.gid=b.gid;
declare
cursor c_stu_grade is select sid,sname,sage,gname from stu a,grade b where a.gid=b.gid;
begin
for v_temp in c_stu_grade loop
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage||' '||v_temp.gname);
end loop;
end;
--隐式游标
/*
sql%found(sql%notfound):跟踪sql执行情况,如果有数据,会返回true
sql%rowcount:跟踪执行的行数
*/
declare
begin
delete from stu2 where did=30;
if(sql%found) then
dbms_output.put_line('删除了'||sql%rowcount||'条数据!');
else
dbms_output.put_line('没有找到数据!');
end if;
commit;
end;
--for游标的另一种写法
--for in 格式:封装格式
select sid,sname,sage,gname from stu a,grade b where a.gid=b.gid; --先做表连接
select sid,sname,sage,gname from stu a,grade b where a.gid=b.gid;
begin
for v_temp in (select sid,sname,sage,gname from stu a,grade b where a.gid=b.gid) loop
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage||' '||v_temp.gname);
end loop;
end;
--ref 游标
1.ref 游标是一种类型,而不是变量
2.ref 游标类型是用来定义游标变量
declare
--声明ref类型
type r_stu is ref cursor;
--定义游标变量
c_stu r_stu;
v_temp stu%rowtype;
begin
--打开游标的过程进行赋值
open c_stu for 'select * from stu';
loop
--提取游标
fetch c_stu into v_temp;
exit when c_stu%notfound;
dbms_output.put_line(v_temp.sid||' '||v_temp.sname);
end loop;
--关闭
close c_stu;
end;
--通用游标
declare
c_stu sys_refcursor;
v_temp stu%rowtype;
begin
--打开游标的过程进行赋值
open c_stu for 'select * from stu';
loop
--提取游标
fetch c_stu into v_temp;
exit when c_stu%notfound;
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage);
end loop;
--关 闭
close c_stu;
end;
--游标实现所有数据表添加序列
declare
cursor c_table is select table_name from user_all_tables;
v_sql varchar2(1000);
begin
for v_temp in c_table loop
v_sql :='create sequence seq_'||v_temp.table_name; 创建序列的语句
execute immediate v_sql;
end loop;
end;
select seq_abc.nextval from dual; --从1开始
--异常
declare
v_score number(3);
v_exception exception;--声明一个异常变量
begin
v_score:='&请输入成绩';
if(v_score<60) then
raise v_exception;--抛出异常
else
dbms_output.put_line('正常成绩:'||v_score);
end if;
--接收异常
exception
when no_data_found then dbms_output.put_line('没有找到数据!');
when invalid_number then dbms_output.put_line('格式问题!');
when others then dbms_output.put_line('错误号:'||sqlcode||' 错误描述:'||sqlerrm);
end;
--存储过程
--无参存储过程
create or replace procedure ups_stu
is
--声明变量
v_sname stu.sname%type;
begin
select sname into v_sname from stu where sid=5;
dbms_output.put_line('用户:'||v_sname);
end ups_stu;
--如何调用
begin
ups_stu;
end;
--带参存储过程
create or replace procedure ups_stu2(
v_sid in stu.sid%type,
v_sname out stu.sname%type
)
is
begin
select sname into v_sname from stu where sid=v_sid;
end ups_stu2;
--调用带参存储过程
declare
v_id stu.sid%type;
v_name stu.sname%type;
begin
v_id:='&请输入编号';
ups_stu2(v_id,v_name);
dbms_output.put_line('存储过程返回的数据:'||v_name);
end;
带参的存储过程 ,传递一个参数 gid ,写游标来接收gid,并输出?
create or replace procedure ups_stu3(
v_gid in stu.gid%type
)
is
cursor c_stu is select * from stu where gid=v_gid;
begin
for v_temp in c_stu loop
dbms_output.put_line(v_temp.sid||' '||v_temp.sname||' '||v_temp.sage);
end loop;
end ups_stu3;
--调用存储过程的另外一种写法! => 指向
declare
v_id stu.gid%type;
begin
v_id:='&请输入年级编号';
ups_stu3(v_gid=>v_id);
end;
--函数
create or replace function fun_stu(v_sid stu.sid%type)
return varchar2 --返回类型不需要指定范围
is
v_sname varchar2(20);
begin
select sname into v_sname from stu where sid=v_sid;
return v_sname;
end fun_stu;
--调用函数 dual
seelct fun_stu(5) as 函数 from dual;
--调用函数2
declare
v_name stu.sname%type;
begin
v_name:=fun_stu(1);
dbms_output.put_line('函数:'||v_name);
end;