oracle中的异常和游标.docx
- 文档编号:28588914
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:15
- 大小:17.96KB
oracle中的异常和游标.docx
《oracle中的异常和游标.docx》由会员分享,可在线阅读,更多相关《oracle中的异常和游标.docx(15页珍藏版)》请在冰豆网上搜索。
oracle中的异常和游标
异常和游标管理
游标:
用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
分类:
静态游标:
分为显式游标和隐式游标。
REF游标:
是一种引用类型,类似于指针。
显式游标:
CURSOR游标名(参数)[返回值类型]IS
Select语句
参数缺省值类型为:
in,无需进行指定。
生命周期:
1.打开游标(OPEN):
解析,绑定。
。
。
不会从数据库检索数据
2.从游标中获取记录(FETCHINTO):
执行查询,返回结果集。
通常定义局域变量作为从游标获取数据的缓冲区。
每次Fetchinto后,记录集会自动卷动。
3.关闭游标(CLOSE)
完成游标处理,用户不能从游标中获取行。
还可以重新打开。
选项:
参数和返回类型
setserveroutputonsize10000
declare
cursoremp_cur(p_deptidinnumber)is
select*fromemployeeswheredepartment_id=p_deptid;
l_empemployees%rowtype;//表的记录类型
begin
dbms_output.put_line(‘Gettingemployeesfromdepartment30’);
openemp_cur(30);
loop
fetchemp_curintol_emp;
exitwhenemp_cur%notfound;
dbms_output.put_line(‘Employeeid‘||l_emp.employee_id||‘is‘);
dbms_output.put_line(l_emp.first_name||‘‘||l_emp.last_name);
endloop;
closeemp_cur;
dbms_output.put_line(‘Gettingemployeesfromdepartment90’);
openemp_cur(90);
loop
fetchemp_curintol_emp;
exitwhenemp_cur%notfound;
dbms_output.put_line(‘Employeeid‘||l_emp.employee_id||‘is‘);
dbms_output.put_line(l_emp.first_name||‘‘||l_emp.last_name);
endloop;
closeemp_cur;
end;
/
隐式游标:
不用明确建立游标变量,分两种:
1.在PL/SQL中使用DML语言,使用ORACLE提供的名为SQL的隐示游标
2.CURSORFORLOOP,用于forloop语句。
1举例:
declare
begin
updatedepartmentssetdepartment_name=department_name;
--where1=2;
dbms_output.put_line(‘update‘||sql%rowcount||’records’);
end;
/
2举例:
这个例子很精典
declare
begin
formy_dept_recin(selectdepartment_name,department_idfromdepartments)
loop
dbms_output.put_line(my_dept_rec.department_id||‘:
’||my_dept_rec.department_name);
endloop;
end;
/
游标属性:
%FOUND:
变量最后从游标中获取记录的时候,在结果集中找到了记录。
%NOTFOUND:
变量最后从游标中获取记录的时候,在结果集中没有找到记录。
%ROWCOUNT:
当前时刻已经从游标中获取的记录数量。
%ISOPEN:
是否打开。
Declare
Cursorempsis
Select*fromemployeeswhererownum<6orderby1;--这种写法太经典了,返回少于6行,并且进行排序(按主键进行排序)。
Empemployees%rowtype;
Rownumber:
=1;
Begin
Openemps;
Fetchempsintoemp;
Loop
Ifemps%foundthen
Dbms_output.put_line(‘Loopingoverrecord‘||row||‘of‘||emps%rowcount);
Fetchempsintoemp;
Row:
=row+1;
Elsifemps%notfoundthen
Exit;---exitloop,notIF
Endif;
Endloop;
Ifemps%isopenthen
Closeemps;
Endif;
End;
/
显式和隐式游标的区别:
尽量使用隐式游标,避免编写附加的游标控制代码(声明,打开,获取,关闭),也不需要声明变量来保存从游标中获取的数据。
REFCURSOR游标:
动态游标,在运行的时候才能确定游标使用的查询。
分类:
强类型(限制)REFCURSOR,规定返回类型
弱类型(非限制)REFCURSOR,不规定返回类型,可以获取任何结果集。
TYPEref_cursor_nameISREFCURSOR[RETURNreturn_type]
Declare
Typerefcur_tisrefcursor;
Typeemp_refcur_tisrefcursorreturnemployee%rowtype;
Begin
Null;
End;
/
强类型举例:
declare
--声明记录类型
typeemp_job_recisrecord(
employee_idnumber,
employee_namevarchar2(50),
job_titlevarchar2(30)
);
--声明REFCURSOR,返回值为该记录类型
typeemp_job_refcur_typeisrefcursor
returnemp_job_rec;
--定义REFCURSOR游标的变量
emp_refcuremp_job_refcur_type;
emp_jobemp_job_rec;
begin
openemp_refcurfor
selecte.employee_id,
e.first_name||‘’||e.last_name“employee_name”,
j.job_title
fromemployeese,jobsj
wheree.job_id=j.job_idandrownum<11orderby1;
fetchemp_refcurintoemp_job;
whileemp_refcur%foundloop
dbms_output.put_line(emp_job.employee_name||‘’’sjobis’);
dbms_output.put_line(emp_job.job_title);
fetchemp_refcurintoemp_job;
endloop;
end;
/
单独select
declare
l_empnoemp.EMPLOYEE_ID%type;
--l_enameemp.ename%type;
begin
selectEMPLOYEE_ID
intol_empno
fromemp;
--whererownum=1;
dbms_output.put_line(l_empno);
end;
/
使用INTO获取值,只能返回一行。
错误处理:
exception
when
…
when
…
end;
exception_expression包括:
1.预定义表达式
2.用户定义表达式
3.PRAGMAEXCEPTION_INIT
预定义
declare
l_deptdepartments%rowtype;
begin
l_dept.department_id:
=100;
l_dept.department_name:
=’HR’;
insertintodepartments(department_id,department_name)
values(l_dept.department_id,l_dept.department_name);
Exception
WhenDUP_VAL_ON_INDEXthen
Dbms_output.put_line(‘heihei’);
end;
/
DUP_VAL_ON_INDEX异常
Exception
WhenDUP_VAL_ON_INDEXthen
Dbms_output.put_line…..
自定义:
declare
l_excexception;
begin
…
raisel_exc;
exception
whenl_excthen
…
end;
/
PRAGMAEXCEPTION_INIT
Declare
L_update_textvarchar2(100):
=
‘update&table_nameset&updated_column_name=‘’:
a’’
where&key_column_name=:
a’;
begin
executeimmediateL_update_textusing‘&updated_column_value’,&key_column_value;
end;
/
Declare
Invalid_column_nameexception;
Pragmaexception_init(Invalid_column_name,-904);
L_update_textvarchar2(100):
=
‘update&table_nameset&updated_column_name=‘’:
a’’
where&key_column_name=:
a’;
begin
executeimmediateL_update_textusing‘&updated_column_value’,&key_column_value;
exception
whenInvalid_column_namethen
dbms_output.put_line(‘hehe’);
end;
/
异常传播:
begin
begin
begin
begin
begin
declare
fnameemployees.first_name%type;
begin
selectfirst_nameintofnamefromemployeeswhere1=2;
--exception
--whenNO_DATA_FOUNDthen
--dbms_output.put_line(‘block6’);
end;
exception
whenNO_DATA_FOUNDthen
dbms_output.put_line(‘block5’);
end;
exception
whenNO_DATA_FOUNDthen
dbms_output.put_line(‘block4’);
end;
exception
whenNO_DATA_FOUNDthen
dbms_output.put_line(‘block3’);
end;
exception
whenNO_DATA_FOUNDthen
dbms_output.put_line(‘block2’);
end;
exception
whenNO_DATA_FOUNDthen
dbms_output.put_line(‘block1’);
end;
/
作用域和可视性:
begin
declare
nested_excpexception;
begin
raisenested_excp;
end;
exception
whennested_excpthen
dbms_output.put_line('haha');
end;
/
whenothersthen
放在最后
begin
declare
nested_excpexception;
begin
raisenested_excp;
end;
exception
whenothersthen
dbms_output.put_line('haha');
dbms_output.put_line(sqlcode||‘is’||sqlerrm);
raise;
end;
/
SQLCODESQLERRM
declare
l_deptdepartments%rowtype;
begin
l_dept.department_id:
=100;
l_dept.department_name:
=’HR’;
insertintodepartments(department_id,department_name)
values(l_dept.department_id,l_dept.department_name);
Exception
Whenothersthen
dbms_output.put_line(sqlcode||‘is’||sqlerrm);
end;
/
declare
l_deptdepartments%rowtype;
begin
l_dept.department_id:
=100;
l_dept.department_name:
=’HR’;
insertintodepartments(department_id,department_name)
values(l_dept.department_id,l_dept.department_name);
Exception
Whenothersthen
Raise_application_error(-20001,‘errormessage!
’);
End;
/
--以下为我自测试语句。
declare
v_1cnpf.card_banci.id%type;
begin
--selectsys_guid()intov_1fromdual;
v_1:
=sys_guid();
dbms_output.put_line(v_1);
end;
/
--这是一个异常的自定义raise用来抛出异常
declare
l_exc1exception;
l_exc2exception;
v_1varchar2(50);
begin
v_1:
='2';
ifv_1='1'then
raisel_exc1;
elsifv_1='2'then
raisel_exc2;
endif;
exception
whenl_exc1then
dbms_output.put_line('这是一个用户自定义错误_1');
whenl_exc2then
dbms_output.put_line('这是一个用户自定义错误_2');
end;
/
--这是一个游标的应用实例
declare
typerecord_empisrecord(EMP_LSHNUMBER(20),CARD_NOVARCHAR2(50));--自定义记录类型
v_recordrl_emp%rowtype;--%rowtype表记录的类型%type表记录的字段类型
v_record_emprecord_emp;
--cursorcur_empisselect*fromrl_empxwherex.card_noin('A3001241','A3001242');
cursorcur_empisselectx.emp_lsh,x.card_nofromrl_empxwherex.card_noin('A3001241','A3001242');
begin
opencur_emp;
dbms_output.put_line('emp_id'||''||'卡号');
loop
fetchcur_empintov_record_emp;--fetch后记录会自动卷动
exitwhencur_emp%NOTFOUND;--循环退出的条件
dbms_output.put_line(v_record_emp.emp_lsh||''||v_record_emp.CARD_NO);
endloop;
closecur_emp;--使用完毕后关闭游标,释放资源
exception
whenothersthen
dbms_output.put_line('doerror');
end;
/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- oracle 中的 异常 游标