`
keepwork
  • 浏览: 334279 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Oracle--异常处理

 
阅读更多

开发者博客www.developsearch.com

 

 

有三种类型的异常错误:

 

    1. 预定义 ( Predefined )错误

 

  ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。

 

    2. 非预定义 ( Predefined )错误

 

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

 

    3. 用户定义(User_define) 错误

 

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

 

参考文章:http://www.cnblogs.com/soundcode/archive/2012/01/10/2318385.html

 

异常处理部分一般放在 PL/SQL 程序体的后半部,结构为:

 

 

EXCEPTION
   WHEN first_exception THEN  <code to handle first exception >
   WHEN second_exception THEN  <code to handle second exception >
   WHEN OTHERS THEN  <code to handle others exception >
END;

 

 

 

预定义说明的部分 ORACLE 异常错误

错误号

异常错误信息名称

说明

ORA-0001

Dup_val_on_index

违反了唯一性限制

ORA-0051

Timeout-on-resource

在等待资源时发生超时

ORA-0061

Transaction-backed-out

由于发生死锁事务被撤消

ORA-1001

Invalid-CURSOR

试图使用一个无效的游标

ORA-1012

Not-logged-on

没有连接到ORACLE

ORA-1017

Login-denied

无效的用户名/口令

ORA-1403

No_data_found

SELECT INTO没有找到数据

ORA-1422

Too_many_rows

SELECT INTO 返回多行

ORA-1476

Zero-divide

试图被零除

ORA-1722

Invalid-NUMBER

转换一个数字失败

ORA-6500

Storage-error

内存不够引发的内部错误

ORA-6501

Program-error

内部错误

ORA-6502

Value-error

转换或截断错误

ORA-6504

Rowtype-mismatch

宿主游标变量与 PL/SQL变量有不兼容行类型

ORA-6511

CURSOR-already-OPEN

试图打开一个已处于打开状态的游标

ORA-6530

Access-INTO-null

试图为null 对象的属性赋值

ORA-6531

Collection-is-null

试图将Exists 以外的集合( collection)方法应用于一个null pl/sql 表上或varray

ORA-6532

Subscript-outside-limit

对嵌套或varray索引得引用超出声明范围以外

ORA-6533

Subscript-beyond-count

对嵌套或varray 索引得引用大于集合中元素的个数

 

 

对这种异常情况的处理,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。1更新指定员工工资,如工资小于1500,则加100
DECLARE
   v_empno employees.employee_id%TYPE := &empno;
   v_sal   employees.salary%TYPE;
BEGIN
   SELECT salary INTO v_sal FROM employees WHERE employee_id = v_empno;
   IF v_sal<=1500 THEN 
        UPDATE employees SET salary = salary + 100 WHERE employee_id=v_empno; 
        DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'员工工资已更新!');     
   ELSE
        DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'员工工资已经超过规定值!');
   END IF;
EXCEPTION
   WHEN NO_DATA_FOUND THEN  
      DBMS_OUTPUT.PUT_LINE('数据库中没有编码为'||v_empno||'的员工');
   WHEN TOO_MANY_ROWS THEN
      DBMS_OUTPUT.PUT_LINE('程序运行错误!请使用游标');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;
 
非预定义的异常处理

对于这类异常情况的处理,首先必须对非定义的ORACLE错误进行定义。步骤如下:

1. 在PL/SQL 块的定义部分定义异常情况:

<异常情况>  EXCEPTION;

2. 将其定义好的异常情况,与标准的ORACLE错误联系起来,使用EXCEPTION_INIT语句:

PRAGMA EXCEPTION_INIT(<异常情况>, <错误代码>);

3. 在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。

 

2删除指定部门的记录信息,以确保该部门没有员工。

INSERT INTO departments VALUES(50, 'FINANCE', 'CHICAGO');

DECLARE
   v_deptno departments.department_id%TYPE := &deptno;
   deptno_remaining EXCEPTION;
   PRAGMA EXCEPTION_INIT(deptno_remaining, -2292);
   /* -2292 是违反一致性约束的错误代码 */
BEGIN
   DELETE FROM departments WHERE department_id = v_deptno;
EXCEPTION
   WHEN deptno_remaining THEN 
      DBMS_OUTPUT.PUT_LINE('违反数据完整性约束!');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;
 
用户自定义的异常处理

当与一个异常错误相关的错误出现时,就会隐含触发该异常错误。用户定义的异常错误是通过显式使用 RAISE 语句来触发。当引发一个异常错误时,控制就转向到 EXCEPTION块异常错误部分,执行错误处理代码。

对于这类异常情况的处理,步骤如下:

1. 在PL/SQL 块的定义部分定义异常情况:

<异常情况>  EXCEPTION;

2. RAISE <异常情况>

 

3. 在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。

 

3更新指定员工工资,增加100

DECLARE
   v_empno employees.employee_id%TYPE :=&empno;
   no_result  EXCEPTION;
BEGIN
   UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno;
   IF SQL%NOTFOUND THEN
      RAISE no_result;
   END IF;
EXCEPTION
   WHEN no_result THEN 
      DBMS_OUTPUT.PUT_LINE('你的数据更新语句失败了!');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;
 
户定义的异常处理

调用DBMS_STANDARD(ORACLE提供的包)包所定义的RAISE_APPLICATION_ERROR过程,可以重新定义异常错误消息,它为应用程序提供了一种与ORACLE交互的方法。

RAISE_APPLICATION_ERROR 的语法如下:

    RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors] );

    这里的error_number 是从 –20,000 到 –20,999 之间的参数,

    error_message 是相应的提示信息(< 2048 字节)

  keep_errors 为可选,如果keep_errors =TRUE ,则新错误将被添加到已经引发的错误列表中。如果keep_errors=FALSE(缺省),则新错误将替换当前的错误列表。

 

4创建一个函数get_salary, 该函数检索指定部门的工资总和,其中定义了-20991-20992号错误,分别处理参数为空和非法部门代码两种错误:

CREATE TABLE errlog(
  Errcode NUMBER,
  Errtext CHAR(40));

CREATE OR REPLACE FUNCTION get_salary(p_deptno NUMBER)
RETURN NUMBER 
AS
  v_sal NUMBER;
BEGIN
  IF p_deptno IS NULL THEN
    RAISE_APPLICATION_ERROR(-20991, ’部门代码为空’);
  ELSIF p_deptno<0 THEN
    RAISE_APPLICATION_ERROR(-20992, ’无效的部门代码’);
  ELSE
    SELECT SUM(employees.salary) INTO v_sal FROM employees 
    WHERE employees.department_id=p_deptno;
    RETURN v_sal;
  END IF;
END;

DECLARE 
  V_salary NUMBER(7,2);
  V_sqlcode NUMBER;
  V_sqlerr VARCHAR2(512);
  Null_deptno EXCEPTION;
  Invalid_deptno EXCEPTION;
  PRAGMA EXCEPTION_INIT(null_deptno,-20991);
  PRAGMA EXCEPTION_INIT(invalid_deptno, -20992);
BEGIN
  V_salary :=get_salary(10);
  DBMS_OUTPUT.PUT_LINE('10号部门工资:' || TO_CHAR(V_salary));

  BEGIN
    V_salary :=get_salary(-10);
  EXCEPTION
    WHEN invalid_deptno THEN
      V_sqlcode :=SQLCODE;
      V_sqlerr  :=SQLERRM;
      INSERT INTO errlog(errcode, errtext) 
      VALUES(v_sqlcode, v_sqlerr);
      COMMIT;
  END inner1;

  V_salary :=get_salary(20);
  DBMS_OUTPUT.PUT_LINE('部门号为20的工资为:'||TO_CHAR(V_salary));

  BEGIN
    V_salary :=get_salary(NULL);
  END inner2;

  V_salary := get_salary(30);
  DBMS_OUTPUT.PUT_LINE('部门号为30的工资为:'||TO_CHAR(V_salary));

  EXCEPTION
    WHEN null_deptno THEN
      V_sqlcode :=SQLCODE;
      V_sqlerr  :=SQLERRM;
      INSERT INTO errlog(errcode, errtext) VALUES(v_sqlcode, v_sqlerr);
      COMMIT;
    WHEN OTHERS THEN
         DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END outer;
 
例5:定义触发器,使用RAISE_APPLICATION_ERROR阻止没有员工姓名的新员式记录插入
CREATE OR REPLACE TRIGGER tr_insert_emp
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
  IF :new.first_name IS NULL OR :new.last_name is null THEN
    RAISE_APPLICATION_ERROR(-20000,'Employee must have a name.');
  END IF;
END;
 
 开发者博客www.developsearch.com
 
 
分享到:
评论

相关推荐

    cx_Oracle-7.3.0.tar.gz

    8. **异常处理**: - `cx_Oracle` 提供了特定的异常类,如 `cx_Oracle.Error` 和 `cx_Oracle.IntegrityError`,可以捕获并处理数据库操作中的错误。 9. **高级特性**: - 支持游标的游标(`cursor.callproc()`)...

    DBD-Oracle-1.74.tar.gz

    3. **错误处理**:在使用DBD::Oracle进行数据库操作时,应始终检查返回的错误代码或异常,以便及时发现并处理问题。 4. **事务管理**:DBD::Oracle支持事务控制,可以使用`begin_work`、`commit`和`rollback`方法...

    cx_Oracle-5.1.2-11g.win32-py2.7.msi

    cx_Oracle还支持更高级的功能,如参数绑定、存储过程调用、事务控制、异常处理等。例如,你可以使用%s占位符来绑定变量,防止SQL注入攻击: ```python query = 'SELECT * FROM table_name WHERE column = %s' ...

    cx_Oracle-5.1.2-11g.win-amd64-py2.7.exe

    除此之外,cx_Oracle还支持异常处理,使你的代码更加健壮: ```python try: # Database operations except cx_Oracle.DatabaseError as e: error, = e.args print(f"Oracle Error code: {error.code}, message: ...

    cx_Oracle-5.2-11g.win-amd64-py2.7.exe

    6. 错误处理:cx_Oracle库提供了异常处理机制,如`DatabaseError`、`IntegrityError`等,帮助开发者捕获并处理数据库相关的错误。 需要注意的是,由于此文件是Python 2.7的,对于使用Python 3的项目,需要下载对应...

    cx_Oracle-5.2.1-11g.win-64--py2.7.exe.zip

    7. **异常处理**:cx_Oracle模块提供了一套完整的异常处理机制,如`cx_Oracle.DatabaseError`,`cx_Oracle.IntegrityError`等,可以帮助开发者更好地处理可能出现的问题。 8. **安全考虑**:在使用cx_Oracle时,应...

    oracle-jdbc-12.2.0.1.zip

    11. **异常处理**: JDBC中的`SQLException`是所有数据库错误的基础异常类,捕获并适当地处理这些异常是编写健壮Java数据库应用的关键。 12. **JNDI查找**: 在企业级应用中,可以通过JNDI(Java Naming and ...

    cx_Oracle-7.3.0-cp36-cp36m-win_amd64.txt

    5. **错误处理**:支持异常处理机制,能够捕获并处理数据库操作中的错误。 6. **兼容性**:兼容多种Oracle数据库版本,能够在不同版本之间灵活切换。 ### 关键知识点五:cx_Oracle与Python版本的兼容性 根据文件名...

    cx_Oracle-5.2.1-11g.win-amd64-py3.5

    6. **异常处理**:cx_Oracle提供了与Oracle相关的异常类,如DatabaseError、OperationalError等,方便捕获和处理数据库操作中的错误。 7. **事务控制**:支持开始、提交、回滚事务,确保数据的一致性和完整性。 8....

    Python库 | cx_Oracle-8.0.0-cp35-cp35m-win_amd64.whl

    通过捕获cx_Oracle模块的异常,可以更好地处理这些问题: ```python try: # Database operation except cx_Oracle.Error as error: print(f'Oracle error occurred: {error}') ``` 总之,cx_Oracle库是Python与...

    cx_Oracle-5.3-11g.x64-py3.6-2.exe.7z

    cx_Oracle库支持各种数据库操作,包括事务控制、参数化查询、游标管理、异常处理等。对于更复杂的操作,如存储过程调用、批量插入、游标的使用,cx_Oracle也提供了相应的接口。 在Python 3.6环境下,cx_Oracle的这...

    cx_Oracle-6.1.tar.gz

    4. **异常处理**:cx_Oracle库封装了Oracle数据库的所有错误和警告,将其转化为Python的异常,方便开发者捕获和处理。 5. **游标属性**:游标对象具有多种属性,如rowcount(返回受影响的行数)、description(返回...

    cx_Oracle-5.1.2.tar.gz

    9. **异常处理**:cx_Oracle定义了一组异常类,如`DatabaseError`、`IntegrityError`和`OperationalError`等,方便开发者捕获并处理与Oracle数据库交互时可能出现的错误。 10. **性能优化**:cx_Oracle支持Oracle的...

    Python库 | filebeat_oracle-0.1.0-py3-none-any.whl

    - **异常处理**:为常见的数据库错误提供异常类,帮助开发者处理错误并捕获异常。 **安装与使用** 在Python环境中,`.whl` 文件是一种预编译的二进制包,可以使用`pip` 工具直接安装,命令通常如下: ```bash pip...

    oracle-ojdbc6-11.2.0.1.0.jar

    - **异常处理**:在编程时,务必处理可能的数据库异常,如连接超时、SQL错误等。 - **性能优化**:了解并应用JDBC的最佳实践,如批量操作、连接池管理和关闭资源,以提高性能和减少资源消耗。 - **驱动注册**:在...

    Oracle-CDC for SSIS

    - 如何处理异常情况,如数据冲突、断点续传等问题。 #### 四、应用场景 1. **数据仓库和报表**: - 将Oracle数据库中的数据变化同步到数据仓库中,以便进行数据分析和报告。 - 支持实时或定期更新,确保业务...

    Oracle_存储过程exception异常处理大全及实例经典最终.docx

    Oracle 存储过程 exception 异常处理大全及实例经典最终 Oracle 存储过程 exception 异常处理大全及实例经典最终是 Oracle 数据库中存储过程的异常处理机制。异常处理是指在程序执行过程中出现的错误或未预料到的...

    java-oracle-demo

    4. 错误处理和异常处理:为了保证程序的健壮性,良好的错误处理和异常处理机制是必不可少的,项目中可能会包含这部分的代码。 5. 连接池:在实际应用中,为了提高效率和管理数据库连接,通常会使用连接池(如C3P0、...

    Oracle-jdbc-12.2.0.1.zip

    3. **错误处理**:使用`SQLException`捕获和处理数据库操作中的异常。 4. **性能优化**:利用批处理、预编译的SQL语句(PreparedStatement)和连接池提高性能。 5. **安全**:考虑使用加密连接,避免SQL注入攻击,...

    1-oracle培训整套教程(存储过程-函数-触发器,异常处理,游标.存储包)

    本套教程全面覆盖了Oracle数据库的核心编程元素,包括存储过程、函数、触发器、异常处理、游标和存储包,这些都是数据库开发和管理中的关键概念。 首先,我们来详细了解存储过程。存储过程是一组预编译的SQL语句,...

Global site tag (gtag.js) - Google Analytics