---
title: "DECLARE ... HANDLER - OceanBase 数据库 V4.5.0 | OceanBase 文档中心"
description: DECLARE ... HANDLER DECLARE ... HANDLER 语句用于指定处理一个或多个异常条件的处理程序。如果出现某一条件，就会执行指定的语句。 语法与参数说明 处理程序声明必须出现在变量或条件声明之后。 DECLARE ... HANDLER 语句的语法如下： DECLARE handler_a…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.5.0

# DECLARE ... HANDLER

更新时间：2026-03-17 16:03:40

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.5.0/zh-CN/700.reference/600.pl-reference/200.pl-mysql/900.pl-exception-handling-statement-mysql/300.declare-handler-mysql.md)  

`DECLARE ... HANDLER` 语句用于指定处理一个或多个异常条件的处理程序。如果出现某一条件，就会执行指定的语句。

## 语法与参数说明

处理程序声明必须出现在变量或条件声明之后。`DECLARE ... HANDLER` 语句的语法如下：

```sql
DECLARE handler_action HANDLER
    FOR condition_value [, condition_value] ...
    statement

handler_action: {
    CONTINUE
  | EXIT
  | UNDO
}

condition_value: {
    mysql_error_code
  | SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
}

```

`statement` 可以是简单的语句，例如 `SET var_name = 1`，也可以是使用 `BEGIN ... END` 块编写的复合语句。详细信息请参见 [PL 语法结构](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004476349)。

`handler_action` 指示处理程序在执行处理程序语句后采取的操作，详情如下：

- `CONTINUE`：继续执行当前程序。
 - `EXIT`：表示处理程序的 `BEGIN ... END` 块中的 Statement 执行完后，退出本次存储过程的执行。
 - `UNDO`：不支持。

`condition_value` 指示激活处理程序的特定条件或条件类别。它可以采取以下形式：

- `mysql_error_code`：表示错误代码的整数字面量，例如 5217 表示"unknown column"。
 - `SQLWARNING`：以 '01' 开头的 `SQLSTATE` 值的简写。
 - `condition_name`：先前使用 `DECLARE ... CONDITION` 指定的条件名称。条件名称可以与错误代码或 `SQLSTATE` 值相关联。
 - `NOT FOUND`：以 '02' 开头的 `SQLSTATE` 值的简写。这与游标的上下文相关，用于控制游标到达数据集末尾时发生的情况。如果没有更多行可用，则会出现 `SQLSTATE` 值为"02000"的 No Data 条件。要检测这种情况，您可以为其设置处理程序或为 `NOT FOUND` 条件设置处理程序。
 - `SQLEXCEPTION`：不以"00"、"01"或"02"开头的 `SQLSTATE` 值的简写。

如果出现未声明处理程序的条件，则根据条件的类别采取如下操作：

- 对于 `SQLEXCEPTION` 条件，存储程序在引发条件的语句处终止，类似于使用了一个 `EXIT` 处理程序。如果该程序被另一个存储程序调用，则调用程序会使用自己的选择规则来处理该条件。
 - 对于 `SQLWARNING` 条件，程序会继续执行，类似于使用了一个 `CONTINUE` 处理程序。
 - 对于 `NOT FOUND` 条件，如果条件被正常引发，则操作为 `CONTINUE`。如果它是由 `SIGNAL` 或 `RESIGNAL` 引发的，则动作为 `EXIT`。

如下示例中，由于使用了 `DECLARE ... HANDLER` 语句声明了当出现重复键错误时执行 `CONTINUE` 操作，所以即使有 `PRIMARY KEY` 的约束，在第二次 `INSERT` 失败后并没有采取默认的 `EXIT` 操作，导致最后的执行结果为 3。

```sql
obclient> CREATE TABLE test.tbl1 (c1 INT, PRIMARY KEY (c1));
Query OK, 0 rows affected

obclient> delimiter //

obclient> CREATE PROCEDURE handler_demo()
       BEGIN
         DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x = 1;
         INSERT INTO test.tbl1 VALUES (101);
         SET @x = 2;
         INSERT INTO test.tbl1 VALUES (101);
         SET @x = 3;
       END;
       //
Query OK, 0 rows affected

obclient> delimiter ;

obclient> CALL handler_demo();
Query OK, 0 rows affected

obclient> SELECT @x;
    +------+
    | @x   |
    +------+
    | 3    |
    +------+
1 row in set

```

如果需要忽略某个条件，可以为其声明一个 `CONTINUE` 处理程序并将其与一个空块相关联。示例如下：

```sql
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;

```

## 块标签的使用限制

块标签的范围不包括块内声明的处理程序的代码。因此，与处理程序关联的语句不能使用 `ITERATE` 或 `LEAVE` 来引用包含处理程序声明的块标签。

如下示例中，`REPEAT` 块具有 `retry_lable` 标签，而 `retry_lable` 标签在块内的 `IF` 语句的范围内，但它不在 `CONTINUE` 处理程序的范围内，因此 `REPEAT` 块引用 `retry_lable` 标签无效并导致错误。

```sql
obclient> CREATE PROCEDURE proc1 ()
   BEGIN
     DECLARE n INT DEFAULT 10;
     retry_lable:
       REPEAT
         BEGIN
           DECLARE CONTINUE HANDLER FOR SQLWARNING
             BEGIN
               ITERATE retry_lable;    # 非法标签
             END;
           IF n < 0 THEN
             LEAVE retry_lable;        # 合法标签
           END IF;
           SET n = n - 1;
         END;
       UNTIL FALSE END REPEAT;
   END //

ERROR 1308 (42000): no matching label: retry_lable

```

使用以下策略可以避免在处理程序中引用外部标签：

- 使用 `EXIT` 处理程序离开该块，并将清理语句放在处理程序主体中。如果不需要块清理，则 `BEGIN ... END` 所包含的处理程序主体可以为空。示例如下：

  ```sql
  DECLARE EXIT HANDLER FOR SQLWARNING
    BEGIN
      block cleanup statements # 块清理语句
    END;

  ```
 - 要继续执行，请在 `CONTINUE` 处理程序中设置一个状态变量，通过在封闭块中检查该状态变量以确定是否调用了处理程序。如下示例使用变量 `done` 来实现这一目的。

  ```sql
  obclient> CREATE PROCEDURE proc2()
     BEGIN
       DECLARE n INT DEFAULT 10;
       DECLARE done INT DEFAULT FALSE;
       retry_lable:
         REPEAT
           BEGIN
             DECLARE CONTINUE HANDLER FOR SQLWARNING
               BEGIN
                 SET done = TRUE;
               END;
             IF done OR n < 0 THEN
               LEAVE retry_lable;
             END IF;
             SET n = n - 2;
           END;
         UNTIL FALSE END REPEAT;
     END;//
  Query OK, 0 rows affected

  ```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
