---
title: "触发器 - OceanBase 数据库 V4.2.1 | OceanBase 文档中心"
description: 触发器 OceanBase 数据库 MySQL 模式兼容 MySQL 5.6 的触发器。触发器是与表相关的数据库对象，触发器可以在语句插入、更新或删除关联表中的行时被激活。例如，您可以通过 INSERT 或 LOAD DATA 语句插入行，并且每插入一行就会激活一次 INSERT 触发器。如果批量插入两行数据，则会触…
---
切换语言

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

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

# 触发器

更新时间：2026-04-16 00:11:36

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.2.1/zh-CN/700.reference/100.oceanbase-database-concepts/700.user-interface-and-query-language/200.PL/100.pl-concepts/200.pl-of-mysql-mode/400.trigger-of-mysql-mode.md)  

OceanBase 数据库 MySQL 模式兼容 MySQL 5.6 的触发器。触发器是与表相关的数据库对象，触发器可以在语句插入、更新或删除关联表中的行时被激活。例如，您可以通过 INSERT 或 LOAD DATA 语句插入行，并且每插入一行就会激活一次 INSERT 触发器。如果批量插入两行数据，则会触发两次触发器。

触发器可以设置为在触发事件之前或之后激活。例如，您可以在插入表的每一行之前或在更新的每一行之后激活触发器。

## 触发器类型

OceanBase 数据库 MySQL 模式当前主要支持以下类型的触发器：

- `INSERT` 型触发器：表示插入某一行时激活触发器，可以通过 `INSERT`、`LOAD DATA`、`REPLACE` 语句触发。
 - `UPDATE` 型触发器：表示更改某一行时激活触发器，可以通过 `UPDATE` 语句触发。
 - `DELETE` 型触发器：删除某一行时激活触发器，可以通过 `DELETE`、`REPLACE` 语句触发。

比较特殊的是 `INSERT INTO ... ON DUPLICATE KEY UPDATE` 语句，每个行都会激活一个 `BEFORE INSERT` 触发器，接着是 `AFTER INSERT` 触发器或者 `BEFORE UPDATE` 与 `AFTER UPDATE` 触发器，是 `AFTER INSERT` 触发器还是 `BEFORE UPDATE` 与 `AFTER UPDATE` 触发器主要取决于行是否有重复的键。

## 创建触发器

您可以使用 `CREATE TRIGGER` 语句创建触发器。

创建触发器的用户需要具备以下权限：

- 当前触发器关联的表的权限，包括 `SELECT`、`INSERT`、`UPDATE`、`DELETE` 等权限。
 - 触发器权限，即 `CREATE` 权限。
 - 触发器激活后要执行的语句的权限。

创建触发器的 SQL 语法如下：

```sql
CREATE
    [DEFINER = user]
    TRIGGER trigger_name
    trigger_time trigger_event
    ON table_name FOR EACH ROW
    [trigger_order]
    trigger_body

trigger_time: { BEFORE | AFTER }

trigger_event: { INSERT | UPDATE | DELETE }

trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

```

**语法说明：**

- 触发器名称 `trigger_name` 必须保持唯一。
 - `tbl_name` 表示建立触发器的表名，即在哪张表上建立触发器。
 - `BEFORE` 或 `AFTER` 表示触发动作的时间，例如触发器将在每一行插入到表中之前还是之后激活。
 - `INSERT`、`UPDATE` 或 `DELETE` 表示触发事件，即激活触发器的操作类型。
 - `FOR EACH ROW` 用于定义触发器的主体，每次触发器激活时就会执行该语句，对于受触发事件影响的每一行都会执行一次。
 - `trigger_order` 子句可以通过关键字 `FOLLOWS` 和 `PRECEDES` 指定具有相同触发器事件和操作时间的触发器顺序。`FOLLOWS` 关键字表示新触发器将在现有触发器之后激活。`PRECEDES` 关键字表示新触发器在现有触发器之前激活。

OceanBase 数据库中也定义了 `NEW.columnName` 和 `OLD.columnName`：

- 在 `INSERT` 型触发器中，`NEW.columnName` 用来表示将要（`BEFORE`）或已经（`AFTER`）插入的新数据。其中，`columnName` 为相应数据表的某一列名。
 - 在 `UPDATE` 型触发器中，`OLD.columnName` 用来表示将要或已经被修改的原数据，`NEW.columnName` 用来表示将要或已经修改后的新数据。
 - 在 `DELETE` 型触发器中，`OLD.columnName` 用来表示将要或已经被删除的原数据。
 - `OLD.columnName` 是只读的，而 `NEW.columnName` 则可以在触发器中使用 `SET` 赋值。

示例：创建一个触发器 `test_trg`，并将其与表 `test` 相关联，以激活 `INSERT` 操作，且触发器充当累加器，将插入到表的列的值求和。

```sql
obclient> CREATE TABLE test (user_id INT, user_num DECIMAL(10,2));
Query OK, 0 rows affected

obclient> CREATE TRIGGER test_trg BEFORE INSERT ON test
       FOR EACH ROW SET @sum = @sum + NEW.user_num;
Query OK, 0 rows affected

```

此外，如果需要定义的触发器有多条执行语句时，可以使用 `BEGIN ... END` 语句，分别表示整个代码块的开始和结束。

`BEGIN ... END` 语句的语法为：

```sql
BEGIN
[statement_list]
END

```

其中，`statement_list` 表示一个或多个语句的列表，列表内的每条语句都必须使用分号（;）结尾。由于在 SQL 语句中，分号（;）是语句结束的标识符，遇到分号表示该段语句已经结束，系统就会开始执行该段语句，最终导致在执行过程中，解释器因为找不到与 `BEGIN` 匹配的 `END` 而报错。为了避免发生此类错误，可以使用 `DELIMITER` 命令来修改语句结束符。

`DELIMITER` 命令示例如下：

```sql
DELIMITER new_delemiter

```

其中，`new_delemiter` 可以设置为 1 个或多个字节长度的符号，默认为分号（;），您可以将其修改为其他符号，例如 `#`。

添加 `DELIMITER` 命令后，`DELIMITER` 命令后的语句再使用分号则不会报错，直到遇到设置的结束符（`#`），才认为该语句结束。

#### 注意

使用 `DELIMITER` 命令修改结束符后，待语句执行结束，请务必将结束符修改为默认符号分号（;）。

示例如下：

obclient> DELIMITER #

obclient> CREATE TRIGGER test_trg BEFORE UPDATE ON test
               FOR EACH ROW
               BEGIN
               IF NEW.user_num < 1 THEN
              SET NEW.user_num  = 1;
              ELSEIF NEW.user_num > 45 THEN
              SET NEW.user_num= 45;
             END IF;
             END;#
Query OK, 0 rows affected

obclient> DELIMITER ;

```

## 触发器的使用限制

MySQL 模式的触发器有以下使用限制：

- 只能在永久表上创建触发器，不能对临时表创建触发器。

  #### 说明

  自 OceanBase 数据库 V4.1.0 BP4 版本起，MySQL 模式下已禁用临时表功能。
 - 触发器不能使用 `CALL` 语句调用将数据返回给客户端或使用动态 SQL 的存储过程，但是允许存储过程或者函数通过 `OUT` 或者 `IN OUT` 类型的参数将数据返回触发器。
 - 触发器中不能使用开启或结束事务的语句段。例如，开始事务（`START TRANSACTION`）、提交事务（`COMMIT`）或回滚事务（`ROLLBACK`），但是可以回滚到一个保存点，即 Savepoint 是允许的，因为回滚到保存点不会结束事务。
 - 外键不会激活触发器。
 - 触发器中不允许返回值，因此触发器中不能有返回语句，如果需要立即停止一个触发器，则需要使用 `LEAVE` 语句。

 上一篇 下一篇 ![有帮助](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) 咨询热线
