标签:line 多行 app var 保留 store varchar output 字符
今天学了异常处理
有预定义异常 与 用户自定义异常 还有 raise_application_error()函数
raise_application_error() 只能把异常抛出而不能处理异常。
预定义异常包括
– NO_DATA_FOUND --没有找到数据
– TOO_MANY_ROWS --找到多行数据
– INVALID_CURSOR --失效的游标
– ZERO_DIVIDE --除数为零
– DUP_VAL_ON_INDEX –唯一索引中插入了重复值
预定义异常的示例:
declare v_id emp.empno%type; --声明变量 begin select empno into v_id from emp where deptno =40; exception --异常处理 when no_data_found then --no_data_found 是使用 select 某字段,然后 into 的时候,该字段没有出。 rollback; dbms_output.put_line(‘没有40号部门记录‘); when too_many_rows then --too_many_rows 是使用 select 某字段,然后 into 的时候,该字段有多个值。 rollback; dbms_output.put_line(‘返回多条记录‘); when others then --其它的异常出现 rollback; dbms_output.put_line(‘出现其他错误.‘); end;
用户自定义异常就是用户定义一个异常情况,遇到这种情况再对这种情况进行处理
因为用户定义的异常不一定是oracle返回的系统错误,系统不会自动触发,需要在声明部分定义。用户定义的异常处理部分基本上和预定义异常相同。
declare salary_level varchar2(1); invalid_salary_level exception; --声明异常 begin salary_level := ‘D‘; if salary_level not in (‘A‘,‘B‘,‘C‘) then raise invalid_salary_level; --触发异常 end if; exception --异常处理 when invalid_salary_level then dbms_output.put_line(‘invalid salary level‘); end;
raise_application_error() 函数只是将异常抛出,不进行异常处理,并且终止程序。而用户自定义异常以及预定义异常不回终止程序,但会终止该 PL/SQL 代码块,所以一个存储过程中可以有多个 PL/SQL 代码块。
关于异常的语法及定义:
什么是异常:
PL/SQL用异常和异常处理器来实现错误处理
Oracle中出现错误的情形通常分为编译时错误(compile-time error)和运行时错误(run-time error)。
异常在PL/SQL执行过程中很可能出现
对异常如果不进行处理,异常可能会中断程序的运行
捕获异常的规则:
在异常部分WHEN 子句没有数量限制
当异常抛出后,控制无条件转到异常处理部分
EXCEPTION 关键词开始异常处理部分 WHEN OTHERS 为最后的一条子句
在异常块中,只有一个句柄会处理异常
关于异常捕获的函数:
SQLCODE 返回错误代码
SQLERRM 返回与错误代码关联的消息
保存任何非预期的异常的错误编码和错误消息
declare v_error_code NUMBER; v_error_message VARCHAR2(255); BEGIN EXCEPTION WHEN OTHERS THEN ROLLBACK; v_error_code := SQLCODE; v_error_message := SQLERRM; INSERT INTO err_logs VALUES (v_error_code, v_error_message); END;
异常的传播
PL/SQL中错误处理的步骤:
步骤1:如果当前块中有该异常的处理器,则执行该异常处理语句块,然后控制权传递到外层语句块 步骤2:如果没有当前异常的处理器,把该异常传播给外层块。然后在外层执行步骤1。如果此语句在最外层语句块,则该异常将被传播给调用环境
没有处理的异常将沿检测异常调用程序传播到外面,当异常被处理并解决或到达程序最外层传播停止。异常是自里向外逐级传递的。
小题:
1.根据员工号,获得员工到目前为止参加工作年限(保留到整数),员工号不存在时提示“此员工号不存在”。
create or replace function get_workyear (v_id in emp.empno%type) return varchar2 IS v_workyear integer; BEGIN select to_char(sysdate,‘yyyy‘)-to_char(hiredate,‘yyyy‘) --两个数字字符串相减的值存到整数型变量中 into v_workyear from emp where emp.empno = v_id; return v_workyear; EXCEPTION when no_data_found then dbms_output.put_line(‘此员工号不存在‘); return -1; END get_workyear;
2.
create or replace procedure store_info (v_empno in myemp.empno%type, v_ename in myemp.ename%type, v_job in myemp.job%type, v_mgr in myemp.mgr%type, v_hiredate in myemp.hiredate%type, v_sal in myemp.sal%type, v_comm in myemp.comm%type, v_deptno in myemp.deptno%type ) IS v_id myemp.empno%type:=0; BEGIN select count(*) into v_id from myemp where myemp.empno = v_empno; if (v_id=0) then insert into myemp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values (v_empno,v_ename,v_job,v_mgr,v_hiredate,v_sal,v_comm,v_deptno); else update myemp set myemp.ename=nvl(v_ename,myemp.ename) , myemp.job=nvl(v_job,myemp.job), myemp.mgr=nvl(v_mgr,myemp.mgr) , myemp.hiredate=nvl(v_hiredate,myemp.hiredate), myemp.sal=nvl(v_sal,myemp.sal) , myemp.comm=nvl(v_comm,myemp.comm), myemp.deptno=nvl(v_deptno,myemp.deptno) where myemp.empno = v_empno ; end if; END store_info; begin store_info(7369,null,null,null,null,2000,null,null); end;
附一张图:
标签:line 多行 app var 保留 store varchar output 字符
原文地址:https://www.cnblogs.com/jiaxinwei/p/10306309.html