加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网_ASP源码网 (https://www.1asp.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

oracle中的cursor

发布时间:2021-01-16 11:15:02 所属栏目:站长百科 来源:网络整理
导读:? ?游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据处理的速度


说明:使用了二重循环,在外循环体中,动态生成游标的SELECT语句,然后打开。通过语句letter:=chr(ascii(letter)+1)可获得字母表中的下一个字母。?

异常处理?
错误处理?
错误处理部分位于程序的可执行部分之后,是由WHEN语句引导的多个分支构成的。错误处理的语法如下:?
EXCEPTION?
WHEN 错误1[OR 错误2] THEN?
语句序列1;?
WHEN 错误3[OR 错误4] THEN?
语句序列2;?
WHEN OTHERS?
语句序列n;?
END;?
其中:?
错误是在标准包中由系统预定义的标准错误,或是由用户在程序的说明部分自定义的错误,参见下一节系统预定义的错误类型。?
语句序列就是不同分支的错误处理部分。?
凡是出现在WHEN后面的错误都是可以捕捉到的错误,其他未被捕捉到的错误,将在WHEN OTHERS部分进行统一处理,OTHENS必须是EXCEPTION部分的最后一个错误处理分支。如要在该分支中进一步判断错误种类,可以通过使用预定义函数SQLCODE( )和SQLERRM( )来获得系统错误号和错误信息。?
如果在程序的子块中发生了错误,但子块没有错误处理部分,则错误会传递到主程序中。?
下面是由于查询编号错误而引起系统预定义异常的例子。?
【训练1】? 查询编号为1234的雇员名字。?

Sql代码?
  1. SET?SERVEROUTPUT?ON??
  2. DECLARE??
  3. v_name?VARCHAR2(10); ??
  4. BEGIN??
  5. ???SELECT???ename ??
  6. ???INTO?????v_name ??
  7. ???FROM?????emp ??
  8. ???WHERE????empno?=?1234; ??
  9. DBMS_OUTPUT.PUT_LINE(‘该雇员名字为:‘||?v_name); ??
  10. EXCEPTION ??
  11. ??WHEN?NO_DATA_FOUND?THEN??
  12. ????DBMS_OUTPUT.PUT_LINE(‘编号错误,没有找到相应雇员!‘); ??
  13. ??WHEN?OTHERS?THEN??
  14. ????DBMS_OUTPUT.PUT_LINE(‘发生其他错误!‘); ??
  15. END;??


执行结果为:?

Sql代码?
  1. 编号错误,没有找到相应雇员! ??
  2. ????????PL/SQL?过程已成功完成。??


说明:在以上查询中,因为编号为1234的雇员不存在,所以将发生类型为“NO_DATA_?
FOUND”的异常。“NO_DATA_FOUND”是系统预定义的错误类型,EXCEPTION部分下的WHEN语句将捕捉到该异常,并执行相应代码部分。在本例中,输出用户自定义的错误信息“编号错误,没有找到相应雇员!”。如果发生其他类型的错误,将执行OTHERS条件下的代码部分,显示“发生其他错误!”。?
【训练2】? 由程序代码显示系统错误。?

Sql代码?
  1. SET?SERVEROUTPUT?ON??
  2. DECLARE??
  3. v_temp?NUMBER(5):=1; ??
  4. BEGIN??
  5. v_temp:=v_temp/0; ??
  6. EXCEPTION ??
  7. ??WHEN?OTHERS?THEN??
  8. DBMS_OUTPUT.PUT_LINE(‘发生系统错误!‘); ??
  9. ????DBMS_OUTPUT.PUT_LINE(‘错误代码:‘||?SQLCODE(?)); ??
  10. ????DBMS_OUTPUT.PUT_LINE(‘错误信息:‘?||SQLERRM(?)); ??
  11. ????????END;??


执行结果为:?

Sql代码?
  1. 发生系统错误! ??
  2. ????????错误代码:?1476 ??
  3. ????????错误信息:ORA-01476:?除数为?0 ??
  4. ????????PL/SQL?过程已成功完成。??


说明:程序运行中发生除零错误,由WHEN OTHERS捕捉到,执行用户自己的输出语句显示错误信息,然后正常结束。在错误处理部分使用了预定义函数SQLCODE( )和SQLERRM( )来进一步获得错误的代码和种类信息。?
预定义错误?
Oracle的系统错误很多,但只有一部分常见错误在标准包中予以定义。定义的错误可以在EXCEPTION部分通过标准的错误名来进行判断,并进行异常处理。常见的系统预定义异常如下所示。?

Sql代码?
  1. 错?误?名?称?错误代码????错?误?含?义 ??
  2. CURSOR_ALREADY_OPEN?ORA_06511???试图打开已经打开的游标 ??
  3. INVALID_CURSOR??ORA_01001???试图使用没有打开的游标 ??
  4. DUP_VAL_ON_INDEX????ORA_00001???保存重复值到惟一索引约束的列中 ??
  5. ZERO_DIVIDE?ORA_01476???发生除数为零的除法错误 ??
  6. INVALID_NUMBER??ORA_01722???试图对无效字符进行数值转换 ??
  7. ROWTYPE_MISMATCH????ORA_06504???主变量和游标的类型不兼容 ??
  8. VALUE_ERROR?ORA_06502???转换、截断或算术运算发生错误 ??
  9. TOO_MANY_ROWS???ORA_01422???SELECT…INTO…语句返回多于一行的数据 ??
  10. NO_DATA_FOUND???ORA_01403???SELECT…INTO…语句没有数据返回 ??
  11. TIMEOUT_ON_RESOURCE?ORA_00051???等待资源时发生超时错误 ??
  12. TRANSACTION_BACKED_OUT??ORA_00060???由于死锁,提交失败 ??
  13. STORAGE_ERROR???ORA_06500???发生内存错误 ??
  14. PROGRAM_ERROR???ORA_06501???发生PL/SQL内部错误 ??
  15. NOT_LOGGED_ON???ORA_01012???试图操作未连接的数据库 ??
  16. LOGIN_DENIED????ORA_01017???在连接时提供了无效用户名或口令??


比如,如果程序向表的主键列插入重复值,则将发生DUP_VAL_ON_INDEX错误。?
如果一个系统错误没有在标准包中定义,则需要在说明部分定义,语法如下:?
错误名 EXCEPTION;?
定义后使用PRAGMA EXCEPTION_INIT来将一个定义的错误同一个特别的Oracle错误代码相关联,就可以同系统预定义的错误一样使用了。语法如下:?
PRAGMA EXCEPTION_INIT(错误名,- 错误代码);?
【训练1】? 定义新的系统错误类型。?

Sql代码?
  1. SET?SERVEROUTPUT?ON??
  2. ????????DECLARE??
  3. ????????V_ENAME?VARCHAR2(10); ??
  4. ????????NULL_INSERT_ERROR?EXCEPTION; ??
  5. ????????PRAGMA?EXCEPTION_INIT(NULL_INSERT_ERROR,-1400); ??
  6. ????????BEGIN??
  7. ????????INSERT?INTO?EMP(EMPNO)?VALUES(NULL); ??
  8. EXCEPTION ??
  9. WHEN?NULL_INSERT_ERROR?THEN??
  10. ????DBMS_OUTPUT.PUT_LINE(‘无法插入NULL值!‘); ??
  11. ??WHEN?OTHERS??THEN??
  12. ????DBMS_OUTPUT.PUT_LINE(‘发生其他系统错误!‘); ??
  13. END;??


执行结果为:?

Sql代码?
  1. 无法插入NULL值! ??
  2. ????????PL/SQL?过程已成功完成。??


? 说明:NULL_INSERT_ERROR是自定义异常,同系统错误1400相关联。?
自定义异常?
程序设计者可以利用引发异常的机制来进行程序设计,自己定义异常类型。可以在声明部分定义新的异常类型,定义的语法是:?
错误名 EXCEPTION;?
用户定义的错误不能由系统来触发,必须由程序显式地触发,触发的语法是:?
RAISE 错误名;?
RAISE也可以用来引发模拟系统错误,比如,RAISE ZERO_DIVIDE将引发模拟的除零错误。?
使用RAISE_APPLICATION_ERROR函数也可以引发异常。该函数要传递两个参数,第一个是用户自定义的错误编号,第二个参数是用户自定义的错误信息。使用该函数引发的异常的编号应该在20 000和20 999之间选择。?
自定义异常处理错误的方式同前。?
【训练1】? 插入新雇员,限定插入雇员的编号在7000~8000之间。?

Java代码?
  1. SET?SERVEROUTPUT?ON ??
  2. DECLARE ??
  3. new_no?NUMBER(10); ??
  4. new_excp1?EXCEPTION; ??
  5. new_excp2?EXCEPTION; ??
  6. BEGIN ??
  7. new_no:=6789; ??
  8. INSERT?INTO?emp(empno,ename) ??
  9. ??VALUES(new_no,?‘小郑‘); ??
  10. ??IF?new_no<7000?THEN ??
  11. ????RAISE?new_excp1; ??
  12. ??END?IF; ??
  13. ??IF?new_no>8000?THEN ??
  14. ????RAISE?new_excp2; ??
  15. ??END?IF; ??
  16. ??COMMIT; ??
  17. EXCEPTION ??
  18. WHEN?new_excp1??THEN ??
  19. ????ROLLBACK; ??
  20. ????DBMS_OUTPUT.PUT_LINE(‘雇员编号小于7000的下限!‘); ??
  21. ????WHEN?new_excp2??THEN ??
  22. ????ROLLBACK; ??
  23. ????DBMS_OUTPUT.PUT_LINE(‘雇员编号超过8000的上限!‘); ??
  24. ????END;??


执行结果为:?
雇员编号小于7000的下限!?
PL/SQL 过程已成功完成。?
说明:在此例中,自定义了两个异常:new_excp1和new_excp2,分别代表编号小于7000和编号大于8000的错误。在程序中通过判断编号大小,产生对应的异常,并在异常处理部分回退插入操作,然后显示相应的错误信息。?
【训练2】? 使用RAISE_APPLICATION_ERROR函数引发系统异常。?

Sql代码?
  1. SET?SERVEROUTPUT?ON??
  2. DECLARE??
  3. New_no?NUMBER(10); ??
  4. BEGIN??
  5. ??New_no:=6789; ??
  6. ?INSERT?INTO????emp(empno,ename) ??
  7. ??VALUES(new_no,?‘JAMES‘); ??
  8. IF?new_no<7000?THEN??
  9. ????ROLLBACK; ??
  10. ????RAISE_APPLICATION_ERROR(-20001,?‘编号小于7000的下限!‘); ??
  11. ??END?IF; ??
  12. ??IF?new_no>8000?THEN??
  13. ????ROLLBACK; ??
  14. ????RAISE_APPLICATION_ERROR?(-20002,?‘编号大于8000的下限!‘); ??
  15. ??END?IF; ??
  16. END;??

(编辑:安卓应用网_ASP源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读