添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Oracle数据库之PL/SQL异常处理

异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的。

PL/SQL程序设计过程中,即使是写得最好的程序也可能会遇到错误或未预料到的事件。一个健壮的程序都应该能够正确处理各种异常情况,并尽可能从中恢复。

1. 异常处理

异常处理是用来处理正常执行过程中未预料的事件。PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会自动终止整个程序运行。

PL/SQL编程过程中,有三种类型的异常:

1.预定义异常

对这种异常情况的处理,无需在程序中定义,当PL/SQL程序违反Oracle规则或超越系统限制时隐式引发。

2.非预定义异常

其他标准的Oracle错误。对这种异常情况的处理,需要用户在程序中定义,然后由Oracle自动将其引发。

3.用户定义异常

程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。

异常处理通常放在PL/SQL程序的后部,语法结构为:

EXCEPTION
    WHEN { exception [ OR exception ]... | OTHERS }
        THEN statement [ statement ]...

2. 预定义的异常处理

常见预定义异常:

ORA-00001 DUP_VAL_ON_INDEX 重复索引值,违反了唯一性限制,当在唯一索引所对应的列上键入重复值时触发 ORA-01001 INVALID_CURSOR 试图使用一个无效的游标 ORA-01012 NOT_LOGGED_ON 没有连接到ORACLE ORA-01017 LOGIN_DENIED 无效的用户名/口令 ORA-01403 NO_DATA_FOUND 没有找到数据时触发 ORA-01422 TOO_MANY_ROWS ORA-01722 INVALID_NUMBER 转换为数字失败时触发 ORA-06511 CURSOR_ALREADY_OPEN 试图打开一个已处于打开状态的游标 ORA-06592 CASE_NOT_FOUND 当case条件都不满足时触发

更多预定义异常见: http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/errors.htm#LNPLS00703

对预定义异常的处理,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。

DECLARE
  stock_price   NUMBER := 9.73;
  net_earnings  NUMBER := 0;
  pe_ratio      NUMBER;
BEGIN
  pe_ratio := stock_price / net_earnings;
  DBMS_OUTPUT.PUT_LINE('运算结果 = ' || pe_ratio);
EXCEPTION
  WHEN ZERO_DIVIDE THEN
    DBMS_OUTPUT.PUT_LINE('/ by zero');
    pe_ratio := NULL;

运行结果:

/ by zero

为避免除0异常,可以采用如下示例2方式解决:

DECLARE
  stock_price   NUMBER := 9.73;
  net_earnings  NUMBER := 0;
  pe_ratio      NUMBER;
BEGIN
  pe_ratio :=
    CASE net_earnings
      WHEN 0 THEN NULL
      ELSE stock_price / net_earnings
DECLARE
  default_number NUMBER := 0;
BEGIN
  INSERT INTO t VALUES(TO_NUMBER('100.00', '9G999'));
EXCEPTION
  WHEN INVALID_NUMBER THEN
    DBMS_OUTPUT.PUT_LINE('使用默认值替换非法数字');
    INSERT INTO t VALUES(default_number);

运行结果:

使用默认值替换非法数字

3. 非预定义的异常处理

非预定义异常有错误号没有名字,处理的办法是:自己定义一个名字,绑定到错误号,捕获错误名。处理这类异常,首先必须对非预定义的Oracle异常进行定义。

myexcp EXCEPTION;

然后使用EXCEPTION_INIT语句与标准的ORACLE错误联系起来,如:

PRAGMA EXCEPTION_INIT(myexcp,-02292);

说明:ORA-02292是违反完整性约束的错误代码。

DECLARE
    myexcp EXCEPTION;
    PRAGMA EXCEPTION_INIT(myexcp,-02292);
    dno scott.emp.deptno%TYPE;
BEGIN
    dno := &dept_no;
    DELETE FROM scott.dept WHERE deptno=dno;
    EXCEPTION 
        WHEN myexcp THEN 
            DELETE FROM scott.emp WHERE deptno=dno;
            DELETE FROM scott.dept WHERE deptno=dno;       

4. 用户定义异常处理

我们可以在任何PL/SQL匿名块,子程序或包的声明部分声明自己的异常。用户定义的异常是通过使用RAISE语句显式触发的。

一般用户定义异常的处理流程为:定义异常->抛出异常->捕获及处理异常。

DECLARE 
   invalidCATEGORY EXCEPTION; -- 定义异常
   category VARCHAR2(10);
BEGIN
   category := '&Category';
   IF category NOT IN ('附件','顶盖','备件') THEN
      RAISE invalidCATEGORY; -- 抛出异常
      DBMS_OUTPUT.PUT_LINE('您输入的类别是'|| category);
   END IF;
EXCEPTION
   WHEN invalidCATEGORY THEN -- 捕获及处理异常
      DBMS_OUTPUT.PUT_LINE('无法识别该类别');

我们可以调用RAISE_APPLICATION_ERROR过程引发并传播应用程序异常,这为应用程序提供了一种与ORACLE交互的方法。

RAISE_APPLICATION_ERROR过程可用于创建用户定义的错误信息,可以在可执行部分和异常处理部分使用,错误编号必须介于–20000 和–20999之间,错误消息的长度可长达2048个字节。

RAISE_APPLICATION_ERROR过程语法:

RAISE_APPLICATION_ERROR (error_code, message[, {TRUE | FALSE}]);

如果指定TRUE,PL/SQL把ERROR_CODE上的错误信息添加到堆栈的顶部。指定FALSE,PL/SQL替换ERROR_CODE错误堆栈,默认值为FALSE。

DECLARE
   empno employees.employee_id%TYPE;
   no_such_row  EXCEPTION;
BEGIN
   empno := &empno;
   UPDATE employees SET salary = salary+100 WHERE id = empno;
   IF SQL%NOTFOUND THEN
      RAISE no_such_row;
   END IF;
EXCEPTION
   WHEN no_such_row THEN 
      RAISE_APPLICATION_ERROR(-20001, '没有待修改的行');
BEGIN
   UPDATE emp SET deptno=80 WHERE empno=1111;
   IF SQL%NOTFOUND THEN
      RAISE_APPLICATION_ERROR(-20001,'该雇员不存在!');
   END IF;
   EXCEPTION
     WHEN OTHERS THEN
        dbms_output.put_line(SQLCODE||'-->'||SQLERRM);

SQLCODE用于取得Oracle错误号。

SQLERRM则用于取得与之相关的错误消息。

pytorch创建张量 pytorch张量赋值

Pytorch简介Pytorch是一个基于Python的深度学习框架,可以代替Numpy在GPU上进行科学计算。什么是TensorTensor即张量,类似于Numpy的ndarrays,tensor可以在GPU上使用以加速计算。Pytorch创建张量的常用方法创建一个未初始化的张量,其值不确定:# 初始化值不确定,由所分配内存的当前值决定 x = torch.empty(5, 3) print(x

java实现国际象棋 国际象棋 编程

与中国象棋类似的,还有国际象棋,知道有人爱玩,于是凭着好奇心,网上研究了一下,跟中国象棋有相似之处,玩法是有些许不一样,不知道象棋最早出于谁之手呢,抽空做一做,最终完成,玩一玩看着还不错吧,这里给讲一讲它的实现过程。可能在国内的有些同学没有玩过国际版的象棋,在此简要说明以下规则,以便了解: 后棋:?皇后,不可越棋; 王棋:?国王,限走一格,特殊走法,首次使用可与未使用过的车易位一次(向车方向走两格