Oracle PL/SQL 编程入门:第九章 异常 高级主题

欢迎来到 Oracle PL/SQL 编程入门 的第九章!在这一章中,我们将深入探讨 PL/SQL 中的异常处理高级主题。通过学习 RAISE_APPLICATION_ERROREXCEPTION_INIT 以及如何使用 SQLCODESQLERRM,你将能够编写更加灵活和强大的错误处理机制。此外,我们还会介绍一些注意事项,并通过实际例子展示它们的用法。准备好迎接新的挑战了吗?让我们开始吧!


第一节:RAISE_APPLICATION_ERROR

RAISE_APPLICATION_ERROR 是一个非常有用的内置函数,它允许你在程序中抛出自定义错误消息,并指定错误代码。

1.1 概念

RAISE_APPLICATION_ERROR 可以用来生成用户定义的错误消息,并将其返回给调用者。这使得你可以为特定的应用场景提供详细的错误信息。

1.2 使用方法

RAISE_APPLICATION_ERROR 函数接受两个参数:

  • 错误代码(范围在 -20000 到 -20999 之间)
  • 错误消息(字符串)

示例:

BEGIN
  IF NOT EXISTS (SELECT 1 FROM employees WHERE employee_id = 100) THEN
    RAISE_APPLICATION_ERROR(-20001, '员工 ID 100 不存在');
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/

输出结果:

ORA-20001: 员工 ID 100 不存在

小贴士:自定义错误消息让你的调试更轻松

RAISE_APPLICATION_ERROR 就像是给你的程序添加了一个“紧急呼叫”按钮,当你遇到特定问题时,可以立即通知用户并提供详细的错误信息。合理使用它可以让你的调试过程更加轻松。


第二节:EXCEPTION_INIT

EXCEPTION_INIT 是一个编译指令,用于将用户定义的异常与特定的 Oracle 错误号绑定在一起。这样可以在异常处理块中直接捕获这些异常。

2.1 概念

EXCEPTION_INIT 允许你将一个自定义异常与一个特定的 Oracle 错误号关联起来,从而在异常处理块中捕获该异常。

2.2 使用方法

使用 PRAGMA EXCEPTION_INIT 来初始化自定义异常。

示例:

DECLARE
  invalid_employee_id EXCEPTION;
  PRAGMA EXCEPTION_INIT(invalid_employee_id, -20001); -- 绑定错误号

  v_employee_id NUMBER := 100;
  v_employee_name VARCHAR2(50);
BEGIN
  SELECT first_name || ' ' || last_name INTO v_employee_name
  FROM employees
  WHERE employee_id = v_employee_id;

  DBMS_OUTPUT.PUT_LINE('员工姓名: ' || v_employee_name);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RAISE_APPLICATION_ERROR(-20001, '员工 ID 100 不存在');
  WHEN invalid_employee_id THEN
    DBMS_OUTPUT.PUT_LINE('自定义异常:无效的员工ID');
END;
/

输出结果:

自定义异常:无效的员工ID

小贴士:EXCEPTION_INIT 让异常处理更清晰

EXCEPTION_INIT 就像是给你的异常处理系统增加了一个“标签”,帮助你更容易地识别和处理特定类型的错误。合理使用它可以让你的异常处理更加清晰。


第三节:SQLCODE and SQLERRM

SQLCODESQLERRM 是两个内置函数,用于获取当前异常的错误代码和错误消息。

3.1 SQLCODE

SQLCODE 返回当前异常的错误代码。对于用户定义的异常,SQLCODE 返回 -20000-20999 之间的值。

3.2 SQLERRM

SQLERRM 返回当前异常的错误消息。它可以提供有关错误的详细信息。

示例:

BEGIN
  RAISE_APPLICATION_ERROR(-20001, '这是一个自定义错误');
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('错误代码: ' || SQLCODE);
    DBMS_OUTPUT.PUT_LINE('错误消息: ' || SQLERRM);
END;
/

输出结果:

错误代码: -20001
错误消息: ORA-20001: 这是一个自定义错误

小贴士:SQLCODE 和 SQLERRM 让错误信息更全面

SQLCODESQLERRM 就像是给你的程序提供了一份详细的“错误报告”,不仅告诉你出了什么问题,还提供了具体的错误代码。合理使用它们可以帮助你更快地定位和解决问题。


第四节:注意事项

在编写 PL/SQL 代码时,有一些常见问题需要注意,以避免潜在的错误和性能问题。

4.1 合理使用异常处理

不要滥用异常处理,尽量只捕获你需要处理的异常。过度使用异常处理会影响程序的性能,并使代码难以维护。

4.2 不要忽略异常

忽略异常(例如使用 WHEN OTHERS THEN NULL)可能会导致潜在的问题被掩盖,影响程序的可靠性。

4.3 使用 RAISE_APPLICATION_ERROR 提供自定义错误消息

有时你需要提供更详细的错误信息,这时可以使用 RAISE_APPLICATION_ERROR 函数。

示例:

BEGIN
  IF NOT EXISTS (SELECT 1 FROM employees WHERE employee_id = 100) THEN
    RAISE_APPLICATION_ERROR(-20001, '员工 ID 100 不存在');
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/

输出结果:

ORA-20001: 员工 ID 100 不存在

小贴士:自定义错误消息让调试更容易

使用 RAISE_APPLICATION_ERROR 提供自定义错误消息就像是给你的程序添加了注释,帮助你更快地找到问题所在。


第五节:代码挑战

现在是时候来挑战一下自己了!我们将通过几个简单的练习来巩固所学的知识。

挑战一:使用 RAISE_APPLICATION_ERROR 处理无效员工ID

编写一个 PL/SQL 块,提示用户输入员工ID,并查询对应的员工姓名。如果找不到匹配的员工记录,则抛出自定义错误并捕获处理。

示例代码:

DECLARE
  v_employee_id NUMBER := &employee_id; -- 输入员工ID
  v_employee_name VARCHAR2(50);
BEGIN
  SELECT first_name || ' ' || last_name INTO v_employee_name
  FROM employees
  WHERE employee_id = v_employee_id;

  DBMS_OUTPUT.PUT_LINE('员工姓名: ' || v_employee_name);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RAISE_APPLICATION_ERROR(-20001, '员工 ID ' || v_employee_id || ' 不存在');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('错误代码: ' || SQLCODE);
    DBMS_OUTPUT.PUT_LINE('错误消息: ' || SQLERRM);
END;
/

执行说明:

  1. 在 SQL*Plus 或 SQL Developer 中运行上述代码块。
  2. 提示输入员工ID,例如 999
  3. 输出结果应为 ORA-20001: 员工 ID 999 不存在

挑战二:使用 EXCEPTION_INIT 处理重复插入

编写一个 PL/SQL 块,尝试插入一条新记录到 employees 表中。如果该表中已经存在相同 employee_id 的记录,则捕获并处理 DUP_VAL_ON_INDEX 异常。

示例代码:

DECLARE
  dup_val_on_index EXCEPTION;
  PRAGMA EXCEPTION_INIT(dup_val_on_index, -1); -- 绑定错误号

  v_employee_id NUMBER := &employee_id; -- 输入员工ID
  v_first_name VARCHAR2(50) := '&first_name'; -- 输入名字
  v_last_name VARCHAR2(50) := '&last_name'; -- 输入姓氏
BEGIN
  INSERT INTO employees (employee_id, first_name, last_name)
  VALUES (v_employee_id, v_first_name, v_last_name);

  DBMS_OUTPUT.PUT_LINE('数据插入成功');
EXCEPTION
  WHEN dup_val_on_index THEN
    DBMS_OUTPUT.PUT_LINE('违反唯一约束:重复的 employee_id');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('错误代码: ' || SQLCODE);
    DBMS_OUTPUT.PUT_LINE('错误消息: ' || SQLERRM);
END;
/

执行说明:

  1. 在 SQL*Plus 或 SQL Developer 中运行上述代码块。
  2. 提示输入 employee_id, first_name, last_name,例如 100, 'John', 'Doe'
  3. 输出结果应为 违反唯一约束:重复的 employee_id

小贴士:动手实践是最好的老师

理论知识固然重要,但真正的技能提升来自于不断的实践。通过这些挑战,你可以加深对 PL/SQL 的理解,并发现自己可能忽略的小细节。勇敢地面对每一个挑战,你会发现编程其实并没有那么难!


第六节:本章总结

在这一章中,我们深入探讨了 PL/SQL 中的异常处理高级主题,包括 RAISE_APPLICATION_ERROREXCEPTION_INIT 以及 SQLCODESQLERRM 的使用。以下是本章的主要内容总结:

总结要点:

  1. RAISE_APPLICATION_ERROR:掌握如何使用 RAISE_APPLICATION_ERROR 抛出自定义错误消息,并指定错误代码。
  2. EXCEPTION_INIT:了解如何使用 PRAGMA EXCEPTION_INIT 将用户定义的异常与特定的 Oracle 错误号绑定在一起。
  3. SQLCODE 和 SQLERRM:熟悉如何使用 SQLCODESQLERRM 获取当前异常的错误代码和错误消息。
  4. 注意事项:合理使用异常处理,避免滥用和忽略异常;使用 RAISE_APPLICATION_ERROR 提供自定义错误消息。

恭喜你完成了第九章的学习!通过这节课,你已经掌握了 PL/SQL 中的异常处理高级主题,并为后续更高级的内容打下了坚实的基础。未来的学习中,我们将继续探索 PL/SQL 的更多功能,如存储过程、触发器等。希望你能继续保持对 PL/SQL 的兴趣,勇敢探索,成为一名熟练的 PL/SQL 用户!

 

你可能感兴趣的:(Oracle,PL/SQL,编程入门,oracle,sql,数据库,异常,异常高级,自定义异常,Exceptions)