默认情况下,SPL 程序中发生的任何错误都会中止该程序的执行。通过使用带有 EXCEPTION 部分的 BEGIN 块,您可以捕获错误并从中恢复。

其语法是 BEGIN 块的常规语法的扩展:

[ DECLARE
    declarations ]
  BEGIN
    statements
  EXCEPTION
    WHEN condition [ OR condition ]... THEN
      handler_statements
  [ WHEN condition [ OR condition ]... THEN
      handler_statements ]...
  END;

如果未发生错误,这种形式的块只执行所有 statements,然后控制权将在 END 之后传递给下一个语句。如果在 statements 中发生错误,则放弃对 statements 的进一步处理,并且控制权将传递给 EXCEPTION 列表。将在该列表中搜索与发生错误匹配的第一个 condition。如果找到匹配项,则将执行相应的 handler_statements,然后控制权将在 END 之后传递给下一个语句。如果未找到匹配项,则错误会传播出去,就好像 EXCEPTION 子句根本不存在一样。带 EXCEPTION 的封闭块可能会捕获错误;如果没有封闭块,则会终止子程序的处理。

特殊的条件名称 OTHERS 与每种错误类型都匹配。条件名称不区分大小写。

如果在所选的 handler_statements 中发生新错误,则它不能被此 EXCEPTION 子句捕获,而是被传播出去。周围的 EXCEPTION 子句可捕获它。

下表列出了可能使用的条件名称:

条件名称 说明
CASE_NOT_FOUND 应用程序遇到这样一种情况:CASE语句中任何 case 的求值结果都不为TRUE,并且没有ELSE条件。
COLLECTION_IS_NULL 应用程序尝试对空集合(如未初始化的嵌套表)调用集合方法。
CURSOR_ALREADY_OPEN 应用程序尝试打开已打开的游标。
DUP_VAL_ON_INDEX 应用程序尝试存储受约束列中当前存在的重复值。
INVALID_CURSOR 应用程序尝试访问未打开的游标。
INVALID_NUMBER 应用程序遇到数据异常(相当于 SQLSTATE 类代码 22)。INVALID_NUMBER是VALUE_ERROR的别名。
NO_DATA_FOUND 没有符合选择标准的行。
OTHERS 应用程序遇到一个异常,该异常未被异常部分中的前提条件捕获。
SUBSCRIPT_BEYOND_COUNT 应用程序尝试引用的嵌套表下标或动态数组超出其初始化或扩展大小。
SUBSCRIPT_OUTSIDE_LIMIT 应用程序尝试引用下标或尝试将动态数组扩展到超出其最大大小限制。
TOO_MANY_ROWS 应用程序遇到满足选择标准的多行(该标准中只允许返回一行)。
VALUE_ERROR 应用程序遇到数据异常(相当于 SQLSTATE 类代码 22)。VALUE_ERROR是INVALID_NUMBER的别名。
ZERO_DIVIDE 应用程序尝试除以零。
User-defined Exception 请参见用户定义的异常
说明 条件名称 INVALID_NUMBER 和 VALUE_ERROR 与 Oracle 数据库不兼容,对于 Oracle 数据库来说,这些条件名称仅用于因字符串转换为数字文本失败而导致的异常。此外,对于 Oracle 数据库,INVALID_NUMBER 异常只适用于 SQL 语句,而VALUE_ERROR 异常只适用于存储过程语句。