plsql中的异常处理

来源:互联网 发布:货单票据打印软件 编辑:程序博客网 时间:2024/05/30 05:29
一、异常的种类
plsql中有三种异常:用户自定义异常(Predefined):程序员自己定义而非oracle公司自己预先定以的一个错误,往往和用户自己的特定业务常见或业务逻辑有关。需要用户在程序中显式的定义错误描述,并由用户自己触发。
预定义异常:由oracle公司预先定义好的,同时具有错误编码(ORA-XXXXX)和错误描述的常见SQL和PL/SQL错误。大约有24个。由SQL自动定义并触发(在条件被满足的时候)。
非预定义异常:有oracle公司预先定义好错误编码(ORA-XXXXX),但是没有错误描述(需要用户在程序中自己定义)的常见SQL和PL/SQL错误。由用户在程序中显示定义,但由SQL自动触发(在条件被满足的时候)。


二、异常的触发和捕获。
1、对异常捕获:
异常在下面的代码块中被捕获:BEGIN
  --some sql scripts
EXCEPTION
  WHEN 1ST_ERROR_DESC THEN
    --some sql scripts for handle the exception
  WHEN 2ND_ERROR_DESC THEN
    --some sql scripts for handle the exception
  WHEN OTHERS THEN
    --catch all the other errors and handle them here
END;


其中,1ST_ERROR_DESC/2ND_ERROR_DESC代表错误描述(包括预定义的,或非预定义的,或用户自定义的),OTHERS 是oracle预定义的,代表所有没有在前面被捕获的异常。


2、对异常的定义
  对预定义异常,由于它已经由oracle定义好了其错误编码和错误描述,因此可以直接使用,无需我们再进行定义。
  而非预定义异常,oracle只定义了其错误编码,但没有定义错误描述;因此在使用前,必须先定义一个错误描述,然后使用PRAGMA EXCEPTION_INIT(ERROR_NAME, ORACLE_ERROR_COD)语句,将错误描述和错误编码绑定起来,之后才能使用。
  对用户自定义的异常,由于是由用户自己触发的,因此没有错误编码,只需要定义错误描述即可。


定义错误描述的语句:ERROR_NAME EXCEPTION;其中,ERROR_NAME就是你定义的错误描述字符串;
绑定错误描述和错误码的语句:PRAGMA EXCEPTION_INIT(ERROR_NAME, ORACLE_ERROR_CODE);其中,ERROR_NAME为错误描述,而ORACLE_ERROR_CODE为oracle预定义的错误编码。


3、捕获各类异常的例子
DECLARE   
  -- 用户自定义了一个异常类别
  e_DuplicateAuthors EXCEPTION;   


  --用户将oracle错误码 ORA-01400 定义为 e_MissingNull
  e_MissingNull EXCEPTION;   
  PRAGMA EXCEPTION_INIT(e_MissingNull, -1400);   


  -- IDs for three authors  
  v_Author1 books.author1%TYPE;   
  v_Author2 books.author2%TYPE;  
  v_Author3 books.author3%TYPE;  


  -- Code and text of other runtime errors
  v_ErrorCode log_table.code%TYPE;   
  v_ErrorText log_table.message%TYPE;  


BEGIN
  -- Find the IDs for the 3 authors of 'Oracle9i DBA 101'  
  SELECT author1, author2, author3   
    INTO v_Author1, v_Author2, v_Author3
    FROM books
   WHERE title = 'Oracle9i DBA 101';   


  -- Ensure that there are no duplicates  
  IF (v_Author1 = v_Author2) OR (v_Author1 = v_Author3) OR (v_Author2 = v_Author3) THEN   
      --抛出一个用户自定义异常
     RAISE e_DuplicateAuthors;   
  END IF;   


EXCEPTION   
  --捕获用户自定义异常,跟捕获预定义异常的方式完全一样
  WHEN e_DuplicateAuthors THEN   
       -- 当异常被触发时,对异常进行处理的语句;其实就是普通的sql或plsql语句。
    INSERT INTO log_table (info) VALUES ('Oracle9i DBA 101 has duplicate authors');
  --捕获预定义异常,它在条件被满足时由sql自动触发(比如没有找到title为'Oracle9i DBA 101'的书籍时)
  WHEN NO_DATA_FOUND THEN  
    v_Author1 := '';
    v_Author2 := '';
    v_Author3 := '';
  --捕获预定义异常,它在条件被满足时由sql自动触发(比如没有找到title为'Oracle9i DBA 101'的书籍时)
  WHEN e_MissingNull THEN  
    dbms_output.put_line('missing some null value');
  -- 发生其他任何异常时,进行处理。OTHERS必须是最后一个语句
  WHEN OTHERS THEN   
    v_ErrorCode := SQLCODE;   
    -- Note the use of SUBSTR here.   
    v_ErrorText := SUBSTR(SQLERRM, 1, 200);   
    INSERT INTO log_table (code, message, info) VALUES  
      (v_ErrorCode, v_ErrorText, 'Oracle error occurred');   


END;   


注意,上面例子中的SQLCODE和SQLERRM是oracle定义的两个函数,其返回值是当前异常的错误码和错误描述。由于它们是函数,因此无法直接被使用,只能先将其返回值存放到一个变量中,然后再使用。
另外,每一个错误描述的长度,最大长度均为512个字节。
0 0
原创粉丝点击