Exception Oracle Error SQLCODE Value 含义
ACCESS_INTO_NULL ORA-06530 -6530 引用对象没有初始化直接为对象赋值
CASE_NOT_FOUND ORA-06592 -6592 如果在when子句中没有case没有包含必须的分支且没有else子句时
COLLECTION_IS_NULL ORA-06531 -6531 集合元素(嵌套表或varray)必须先初始化,没有则触发该错误
CURSOR_ALREADY_OPEN ORA-06511 -6511 重新打开已经打开的游标
DUP_VAL_ON_INDEX ORA-00001 -1 当在唯一索引列上键入重复值时
INVALID_CURSOR ORA-01001 -1001 当试图在不合法的游标上操作时
INVALID_NUMBER ORA-01722 -1722 内嵌sql语句不能有效地将字符转为数字,如100写成了1oo
LOGIN_DENIED ORA-01017 -1017 当执行PL/SQL程序时,需要登录oracle,而提供的用户密码不对时
NO_DATA_FOUND ORA-01403 +100 当执行select into操作没有返回行时
NOT_LOGGED_ON ORA-01012 -1012 执行PLSQL应用程序时,没有登录到数据库
PROGRAM_ERROR ORA-06501 -6501 出现该问题,说明PL/SQL内部出现问题
ROWTYPE_MISMATCH ORA-06504 -6504 当执行赋值操作,宿主游标变量和PL/SQL游标变量返回的类型不匹配
SELF_IS_NULL ORA-30625 -30625 使用对象类型时,在null实例上调用成员时(必须先初始化)
STORAGE_ERROR ORA-06500 -6500 PL/SQL块运行,当内存不足或内存被损坏时
SUBSCRIPT_BEYOND_COUNT ORA-06533 -6533 当使用嵌套表或varray时,其元素下标超出了元素范围
SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 -6532 当使用嵌套表或varray时,其元素下标为赋值时
SYS_INVALID_ROWID ORA-01410 -1410 将字符串转换为rowid时,必须使用有效的字符串
TIMEOUT_ON_RESOURCE ORA-00051 -51 等待超时
TOO_MANY_ROWS ORA-01422 -1422 当执行select into操作返回多行时
VALUE_ERROR ORA-06502 -6502 当在PL/SQL块赋值操作时,变量长度不足以容纳实际数据
ZERO_DIVIDE ORA-01476 -1476 当使用PL/SQL块时,使用数字除0
对于非定义例外:
对于自己定义的例外,可以自己定义 pragma exception_init 来定义出现定义的例外名称和例外的sqlcode。
declare
e_exception exception;
pragma exception_init(e_exception, -2291);
e_no_employ exception;
begin
update emp set deptno = &dno where empno = &eno;
if sql%notfound then
raise e_no_employ;
end if;
exception
when e_exception then
dbms_output.put_line('该部门不存在');
when e_no_employ then
dbms_output.put_line('该雇员不存在');
end;
例外函数的使用:
1)SQLCODE函数用于取得oracle错误号;
2)SQLERRM函数用于取得与之相关的错误消息;
3)在存储过程、函数、包中使用RAISE_APPLICATION_ERROR可以自定义错误号和错误信息。
undef v_sal
declare
v_ename emp.ename%type;
begin
select ename into v_ename from emp where sal = &v_sal;
dbms_output.put_line('雇员名:' || v_ename);
exception
when no_data_found then
dbms_output.put_line('不存在工资为:' || &v_sal || '的雇员');
when others then
dbms_output.put_line('错误号:' || sqlcode);
dbms_output.put_line(sqlerrm);
end;
2、raise_application_error
该过程用于在PL/SQL应用程序中自定义错误消息。注意,该过程只能在数据库端的子程序(过程、函数、包、触发器)中使用,而不能在匿名块和
客户端的子程中使用。
raise_application_error语法如下:
raise_application_error(error_number,message[,{true | false}]);
其中:
error_number表示定义错误号,该错误号必须在-20000到-20999之间的负整数;
message用于指定错误消息,并且该长度不能超过2048字节;
第三个参数为可选参数,若为true,则该错误会被放在先前错误堆栈中;如果设为false(默认值),则会替换先前所有错误。
create or replace procedure raise_comm(eno number, commission number) is
v_comm emp.comm%type;
begin
select comm into v_comm from emp where empno = eno;
if v_comm is null then
raise_application_error(-20001, '该雇员无补助');
end if;
exception
when no_data_found then
dbms_output.put_line('该雇员不存在');
end;
/*2011-6-2关于例外增加部分
如何在一个循环中扑捉例外并能继续执行--解决办法,在loop里面再增加一个块,如下代码所示:
如果是将例外直接放到最后那么遇到一条错误的记录就直接跳出不执行了。
TYPE v_fid_varray IS TABLE OF l_interest_s.g3e_fid%TYPE;
v_fid v_fid_varray;
v_name VARCHAR2(10);
CURSOR fid_cur IS
SELECT g3e_fid
FROM gc_netelem
WHERE g3e_fno = 15000
AND district IS NULL;
BEGIN
OPEN fid_cur;
LOOP
FETCH fid_cur BULK COLLECT
INTO v_fid LIMIT 10000;
IF v_fid IS NOT NULL AND v_fid.count > 0 THEN
FOR i IN v_fid.first .. v_fid.last LOOP
BEGIN
SELECT a.name
into v_name
FROM p_region_s a, l_interest_s b
WHERE sdo_relate(a.gwm_geometry,
b.gwm_geometry,
'MASK = ANYINTERACT') = 'TRUE'
AND b.g3e_fid = v_fid(i);
EXCEPTION
WHEN no_data_found THEN
v_name := NULL;
UPDATE gc_netelem t
SET t.district = v_name,
t.district_id = pkg_public.f_getdistinctid(v_name, '')
WHERE t.g3e_fid = v_fid(i);
END;
END LOOP;
COMMIT;
END IF;
EXIT WHEN fid_cur%NOTFOUND;
END LOOP;
CLOSE fid_cur;
END;
*/
PLSQL编译警告
1、PLSQL警告分类
1)severe:该中警告用于检查可能出现的不可预料结果或错误结果,例如参数的别名问题。
2)performance:该类警告用于检查可能引起的性能问题,例如在执行insert操作时为number列提供了varchar2类型的数据。
3)informational:该类警告用于检查子程序中的死代码。
4)all:该关键字用于检查所有警告(severe,performance,informational)。
2、控制PL/SQL警告信息
在编译时是否会出现上述的几种警告类型,由PLSQL_WARNINGS参数控制。该初始化参数可以在系统级或会话级设置,也可以在ALTER PROCEDURE命令中进行设置。
ALTER SYSTEM SET PLSQL_WARNINGS='ENABLE:ALL';
ALTER SESSION SET PLSQL_WARNINGS='ENABLE:PERFORMANCE';
ALTER PROCEDURE hello COMPILE PLSQL_WARNINGS='ENABLE:PERFORMANCE';
ALTER SESSION SET PLSQL_WARNINGS='DISABLE:ALL';
ALTER SESSION SET PLSQL_WARNINGS='ENABLE:SEVERE','DISABLE:PERFORMANCE','ERROR:06002';
激活或禁止PL/SQL编译警告还可以使用PL/SQL系统包DBMS_WARNINGS。
CALL DBMS_WARNING.set_warning_setting_string('ENABLE:ALL','SESSION');
3、使用PL/SQL编译警告
1)检测死代码
--以下为含有死代码的一个过程(死代码即指在在程序中永不被执行的代码)
create or replace procedure dead_code as
x number :10;
begin
if x = 10 then
x :20;
else
x :100; --else永不会执行到
end if;
end dad_code;
为了检测该子程序是否包含死代码,必须先激活警告检查,然后重新编译子程序,最后使用show errors命令显示警告错误。
alter session set plsql_warnings='enable:informational';
alter procedure dead_code compile;
show errors;
2)检测引起性能问题的代码
create or replace procedure update_sal(name varchar2, salary varchar2) is
begin
update emp set sal = salary where ename = name;
end;
SQL> alter session set plsql_warnings='enable:performance';
Session altered
SQL> alter procedure update_sal compile;
Procedure altered
SQL> show errors;
Errors for PROCEDURE SCOTT.UPDATE_SAL:
LINE/COL ERROR
-------- ---------------------------------------------------
3/26 PLW-07202: 绑定类型可能会导致从列类型转换为其它类型