续
10、异常和错误处理
1>、Oracle提供异常情况(exception)和异常处理(exception handler)来实现对错误的处理。
2>、异常情况(exception)指在正常执行过程中未预料的事件,程序块的异常处理预定义错误和自定义错误,运行PL/SQL块时一旦产生异常而没有指出如何处理时,就会自动终止整个PL/SQL块的运行。
3>、异常错误分为3类(预定义错误、非预定义错误、自定义错误)
预定义错误:无需在程序中定义,由Oracle自动引发,共24个,直接在异常中使用。
非预定义错误:需在程序中定义,由Oracle自动引发
自定义错误:需在程序中定义,且需在程序中引发。
1)预定义错误
exception
when No_data_found then
dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss') ||'execute failure');
2)非预定义错误
--定义错误
<异常情况> exception;
--与标准的Oracle错误关联
pragma exception_init(<异常情况>,<异常代码>);
--处理错误
exception
when foundError then
dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss') ||'execute failure');
3)自定义错误
--定义错误
<异常情况> exception;
--通过raise引发错误
raise 异常情况
--处理错误
exception
when raiseError then
dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss') ||'execute failure');
4)修改自定义错误消息
dbms_standard.raise_application_error(errorNumber,errorCode,errorsMsg);
errorNumber:错误编号: -20000~-20999
errorMsg:提示的错误消息(<2014KB)
errorFlag:true 将错误添加到错误列表,false 替换当前的错误列表,缺省为false
dbms_standard.raise_application_error(-20001,'错误的消息');
记录错误关键字:
sqlcode:错误编号 如:6502
sqlerrm:错误消息 如:ORA-06502: PL/SQL: 数字或值错误 : character string buffer too small (<500KB)
dbms_output.put_line('错误编号_' || sqlcode || '_错误信息_' || sqlerrm);
when others exception必须放在异常处理部分的最后面,以作为缺省异常的处理,when … exception 没有数量限制,没被处理的异常将检测调用异常的程序,并将异常传播到外面,异常被处理并被解决或达到最外层循环后停止,在声明部分的抛出的异常将控制转到上一层部分。
11、函数和存储过程
1> 函数:
create [or replace] function functionName
(arg1 [{in out in out}] type1 default value1,
...
argn [{in out in out}] typen default valuen)
[authid definer|current_user]--权限控制
return resultType
{is | as}
变量的声明部分
begin
执行语句部分
return expression
exception
异常处理部分
end functionName;
in out in out--表示参数的模式,有入参、出参,不写的话默认为入参,其中只能为入参设置默认值,当调用函数后,不指定入参的值时,就使用入参的默认值。
create or replace function funTranslateRole(v_roleId in varchar2,
v_result out varchar2)
return varchar2
is
role_id varchar2(20); --角色编号
begin
role_id := v_roleId;
if (role_id = 'project_sz') then
v_result := role_id || '_表示的是_客服';
else
v_result := role_id || '_表示的是_未知';
end if;
return v_result;
dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss') || '处理成功');
exception
when others then
dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss') || '处理失败');
end funTranslateRole;
1)位置表示法
--argvalue1,argvalue2,..argvaluen
funTranslateRole(v_roleId,v_result)
2)名称表示法
--这种方式与参数的顺序没关系,v_result 、 v_roleId与函数中的参数名称需一致
declare
roleId varchar2(20); --角色编号
vresult varchar2(60); --角色的结果
begin
roleId := 'project_bj';
vresult := funTranslateRole(v_result => vresult, v_roleId => roleId);
dbms_output.put_line(vresult);
end;
3)组合(名称表示+位置表示法)
如果前一个参数用名称表示法,则后面的所有参数都要用名称表示法。
--调用方式
declare
v_roleId varchar2(20); --角色编号
v_result varchar2(60); --角色的结果
begin
v_roleId := 'project_bj';
v_result := funTranslateRole(v_roleId,v_result);
dbms_output.put_line(v_result);
end;
2> 存储过程:
create [or replace] procedure procedure Name
(arg1 [{in out in out}] type1 default value1,
...
argn [{in out in out}] typen default valuen)
[authid definer|current_user]--权限控制
{is |as}
变量的声明部分
begin
执行语句部分
exception
异常处理部分
end procedureName;
in out in out—表示参数的模式,有入参、出参,不写的话默认为入参,其中只能为入参设置默认值,当调用函数后,不指定入参的值时,就使用入参的默认值。
create or replace procedure proTranslateRole(v_roleId in varchar2,
v_result out varchar2)
is
role_id varchar2(20); --角色编号
begin
role_id := v_roleId;
if (role_id = 'project_sz') then
v_result := role_id || '_表示的是_客服';
else
v_result := role_id || '_表示的是_未知';
end if;
dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss') || '处理成功');
exception
when others then
dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss') || '处理失败');
end proTranslateRole;
1)位置表示法
--argvalue1,argvalue2,..argvaluen
proTranslateRole(v_roleId,v_result)
2)名称表示法
--这种方式与参数的顺序没关系,v_result 、 v_roleId与函数中的参数名称需一致
declare
roleId varchar2(20); --角色编号
vresult varchar2(60); --角色的结果
begin
roleId := 'project_bj';
vresult := proTranslateRole (v_result => vresult, v_roleId => roleId);
dbms_output.put_line(vresult);
end;
3)组合(名称表示+位置表示法)
如果前一个参数用名称表示法,则后面的所有参数都要用名称表示法。
--调用方式1
declare
v_roleId varchar2(20); --角色编号
v_result varchar2(60); --角色的结果
begin
v_roleId := 'project_bj';
v_result := proTranslateRole (v_roleId,v_result);
dbms_output.put_line(v_result);
end;
--调用方式2
exec[ute] 存储过程名称(参数1,..参数n);
--可以在PL/SQL块中建立本地函数和过程,但不能使用 create or replace关键字
1) 函数与过程的差异
<1>、如果要返回多个值或不返回值,可以使用过程;如果只返回1个值,可以使用函数。
<2>、过程用于执行一系列的动作,而函数用于计算和返回1个值。
<3>、可以在SQL语句内部通过调用函数来完成复杂的计算,而过程则做不到。
Oracle PL/SQL编程基础简介及实践 到此结束;
下期将给出Oracle 关键字以及模板;
敬请期待....
本文分享自微信公众号 - Oracle优化大师,如有侵权,请联系 service001@enmotech.com 删除。