---
title: "CREATE TRIGGER - OceanBase 数据库 V4.2.1 | OceanBase 文档中心"
description: CREATE TRIGGER CREATE TRIGGER 语句用于创建或替换数据库触发器。 当发生指定条件时，数据库将自动运行触发器。 功能适用性 该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版仅提供 MySQL 模式。 前提条件 要在用户自己的 Schema 或 Schema …
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

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

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

# CREATE TRIGGER

更新时间：2026-07-15 22:01:31

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.2.1/zh-CN/700.reference/500.sql-reference/300.pl-reference/300.pl-oracle/1100.ddl-operations-on-stored-pl-units-oracle/1100.create-trigger-oracle.md)  

`CREATE TRIGGER` 语句用于创建或替换数据库触发器。

当发生指定条件时，数据库将自动运行触发器。

#### 功能适用性

该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版仅提供 MySQL 模式。

## 前提条件

要在用户自己的 Schema 或 Schema 的表上创建触发器，必须具有 `CREATE TRIGGER` 的系统权限。

要在其他用户的 Schema（`schema.SCHEMA`）中创建触发器，必须具有 `CREATE ANY TRIGGER` 的系统权限。

如果触发器执行 SQL 语句或调用存储过程或函数，则触发器的所有者必须具有执行这些操作所需的权限。这些权限必须直接授予使用者，而不是通过角色获得。

## 语法

`create_trigger` 的语法如下：

```sql
CREATE [OR REPLACE] TRIGGER
plsql_trigger_source
BEGIN
  triggered_action;
END;

```

其中：

- `plsql_trigger_source` 的语法如下：

  ```sql
  [schema.] trigger_name
    { simple_dml_trigger
     | instead_of_dml_trigger
     | trigger_ordering_clause
   }

  ```
 - `simple_dml_trigger` 的语法如下：

  ```sql
  { BEFORE | AFTER } dml_event_clause [ referencing_clause ] [ FOR EACH ROW ]
  [ ENABLE | DISABLE ] [ WHEN ( condition ) ] trigger_body

  ```
 - `instead_of_dml_trigger` 的语法如下：

  ```sql
  INSTEAD OF { DELETE | INSERT | UPDATE } [ OR { DELETE | INSERT | UPDATE } ]...
  ON [ schema. ] view
  [ referencing_clause ] [ FOR EACH ROW ]
  [ ENABLE | DISABLE ] trigger_body

  ```
 - `trigger_ordering_clause` 的语法如下：

  ```sql
  { FOLLOWS | PRECEDES } [ schmema.] trigger_name [ , [ schmema.] trigger_name ]...

  ```
 - `dml_event_clause` 的语法如下：

  ```sql
  { DELETE | INSERT | UPDATE [ OF column [, column ]... ] }
  [ OR { DELETE | INSERT | UPDATE [ OF column [, column]... ] }...]
  ON [ schema.] { table | view }

  ```
 - `referencing_clause` 的语法如下：

  ```sql
  REFERENCING
  { OLD [ AS ] old
  | NEW [ AS ] new
  | PARENT [ AS ] parent
  }..

  ```
 - `trigger_body` 的语法如下：

  ```sql
  { plsql_block | CALL routine_clause }

  ```

## 语义

| 语法 | 关键字或语法节点 | 说明 |
| --- | --- | --- |
| create_trigger | OR REPLACE | 重新创建该触发器（如果存在），然后重新编译。 在重新定义触发器之前被授予该触发器权限的用户仍然可以访问该触发器而无需重新获得权限。 |
| plsql_trigger_source | trigger_name | 要创建的触发器名称。 |
| plsql_trigger_source | schema | 该触发器所在的 Schema 名称。默认值为当前用户的 Schema。 |
| plsql_trigger_source | simple_dml_trigger | 创建一个简单的 DML 触发器。 |
| plsql_trigger_source | instead_of_dml_trigger | 创建 `INSTEAD OF` DML 触发器。 `INSTEAD OF` 触发器可以读取 `:OLD` 和 `:NEW` 值，但不能更改 `:OLD` 和 `:NEW` 值。 |
| plsql_trigger_source | trigger_ordering_clause | 指定具有相同时间点的触发器的触发顺序。所指定的触发器必须存在并已成功编译，但不需要启用该触发器。 |
| simple_dml_trigger | BEFORE | 使数据库在运行触发事件之前触发相应触发器。对于行级触发器，将在更改每个行之前触发该触发器。 在 `BEFORE` 语句级触发器中，触发器主体无法读取 `:NEW` 或 `:OLD`。（在 `BEFORE` 行级触发器中，触发器主体可以读取和写入 `:OLD` 和 `:NEW` 字段。） |
| simple_dml_trigger | AFTER | 使数据库在运行触发事件之后触发相应触发器。对于行级触发器，将在更改每个行之后触发该触发器。 在 `AFTER` 语句级触发器中，触发器主体无法读取 `:NEW` 或 `:OLD`。（在 `AFTER` 行级触发器中，触发器主体可以读取和写入 `:OLD` 和 `:NEW` 字段。） |
| simple_dml_trigger | FOR EACH ROW | 将触发器创建为行级触发器。 当受触发语句影响并满足 `WHEN` 条件中定义的可选触发约束时，数据库将触发行触发。 如果省略此子句，则触发器是语句级触发器。如果满足可选触发约束，则只有在执行触发语句时，数据库才会触发语句级触发。 |
| simple_dml_trigger | [ ENABLE \| DISABLE ] | 以启用（默认）或禁用创建触发器。在禁用状态下创建触发器可以确保在启用触发器之前能够正确编译该触发器。 |
| simple_dml_trigger | WHEN (condition) | 指定 SQL 条件，数据库对触发语句影响的每一行进行评估。如果受影响行的`condition` 值为 `TRUE`，则`trigger_body` 在该行运行；否则，`trigger_body` 不会针对该行运行。 无论条件的值如何，触发语句都会运行。在 `condition` 语句中，请勿在关联名称 `NEW`、`OLD` 或 `PARENT` 之前放置冒号（:）。 如果指定 `WHEN (condition)`，则还必须指定 `FOR EACH ROW`。`condition` 不能包含子查询或 PL 表达式（例如，调用用户自定义的函数）。 |
| simple_dml_trigger | trigger_body | 数据库用来触发触发器的 PL 块或 `CALL` 子程序。`CALL` 子程序是 PL 包裹的 PL 子程序。 如果 `trigger_body` 是一个 PL 块，并且包含错误，则 `CREATE [OR REPLACE]` 语句将执行失败。 |
| simple_dml_trigger | dml_event_clause | 用于定义在触发器中触发 DML 事件的条件。DML 事件包括插入（INSERT）、更新（UPDATE）和删除（DELETE）操作。 |
| instead_of_dml_trigger | view | 要在其上创建触发器的视图名称。 |
| instead_of_dml_trigger | FOR EACH ROW | `INSTEAD OF` 触发器始终是行触发器。 |
| instead_of_dml_trigger | [ ENABLE \| DISABLE ] | 启用或禁用触发器，默认为启用触发器。在禁用状态下创建触发器，可以确保正确编译该触发器后再启用触发器。 |
| instead_of_dml_trigger | DELETE | 如果触发器是在视图上创建的，那么每当 `DELETE` 语句从其所定义的表中删除一行时，就会触发触发器。 |
| instead_of_dml_trigger | INSERT | 如果触发器是在视图上创建的，则只要 `INSERT` 语句向其所定义的表中添加行时，就会使数据库触发触发器。 |
| instead_of_dml_trigger | UPDATE | 如果触发器是在视图上创建的，那么每当 `UPDATE` 语句更改其所定义的表中列的值时，会导致数据库触发触发器。 |
| instead_of_dml_trigger | schema | 该触发器所在的 Schema 名称。默认值为当前用户的 Schema。 |
| instead_of_dml_trigger | trigger_body | 数据库用来触发触发器的PL 块或 `CALL` 子程序。`CALL` 子程序是 PL 包裹的 PL 子程序。 如果 `trigger_body` 是一个 PL 块，并且包含错误，则 `CREATE [OR REPLACE]` 语句将执行失败。 |
| trigger_ordering_clause |  | 指定具有相同时间点的触发器的触发顺序。所指定的触发器必须存在并已成功编译，但不需要启用该触发器。 |
| trigger_ordering_clause | FOLLOWS | 指示正在创建的触发器必须在指定的触发器之后触发。 |
| trigger_ordering_clause | PRECEDES | 指示正在创建的触发器必须在指定的触发器之前触发。 |
| triggered_action |  | 指定触发器所执行的动作或逻辑，包括任何需要在触发器被触发时执行的 SQL 语句、条件判断、存储过程调用等内容。在触发器的 triggered_action 部分可以包含对变量的操作、条件判断、写入数据库操作等，实现触发器需要执行的业务逻辑。有关触发器中判断的条件谓词信息，参见下文 [条件谓词](#条件谓词)。 |

### 条件谓词

条件谓词用于在触发器中检测触发 DML 语句的条件，以确定触发器应该执行的逻辑。

#### 说明

对于 OceanBase 数据库 V4.2.1 版本，从 V4.2.1 BP8 版本开始在条件谓词中支持 `CURSOR`。

- `UPDATING`：用于在触发器中判断是否有更新操作发生。当触发器中使用 `IF UPDATING THEN` 语句时，表示如果触发的操作是一个 `UPDATE` 操作，则条件为真（`TRUE`），允许在触发器中执行特定于更新操作的逻辑。
 - `UPDATING('column_name')`：用于在触发器中判断是否有特定列（`column_name`）的更新操作发生。当触发器中使用 `IF UPDATING('column_name') THEN` 语句时，表示如果触发的操作是一个 `UPDATE` 操作，并且指定的列（`column_name`）被更新了，则条件为真（`TRUE`），允许在触发器中针对特定列的更新执行特定的逻辑。
 - `INSERTING`：用于在触发器中判断是否有插入操作发生。当触发器中使用 `IF INSERTING THEN` 语句时，表示如果触发的操作是一个 `INSERT` 操作，则条件为真（`TRUE`），允许在触发器中执行特定于插入操作的逻辑。
 - `DELETING`：用于在触发器中判断是否有删除操作发生。当触发器中使用 `IF DELETING THEN` 语句时，表示如果触发的操作是一个 `DELETE` 操作，则么条件为真（`TRUE`），允许在触发器中执行特定于删除操作的逻辑。

## 示例

示例 1：创建 DML 触发器 `del_new_region`。

```shell
CREATE OR REPLACE TRIGGER del_new_region
      BEFORE DELETE ON regions
      FOR EACH ROW
      WHEN (old.region_id >3)
   BEGIN
      INSERT INTO reg_his(region_id , region_name )
           VALUES( :old.region_id, :old.region_name );
   END;
 /

```

示例 2：创建触发器 `tri2_t` 在触发器 `tri1_t` 之后执行。

```shell
CREATE SEQUENCE seq_tri INCREMENT BY 1 START WITH 1 NOMAXVALUE MINVALUE 0 NOCYCLE NOCACHE;
CREATE TABLE t(c1 INT, c2 INT);
CREATE TABLE msg (c1 INT PRIMARY KEY, c2 VARCHAR(100));
CREATE OR REPLACE TRIGGER tri1_t BEFORE INSERT ON t FOR EACH ROW
BEGIN
  INSERT INTO msg VALUES (seq_tri.NEXTVAL, 'BEFORE INSERT tri1_t');
END;
/

CREATE OR REPLACE TRIGGER tri2_t BEFORE INSERT ON t FOR EACH ROW FOLLOWS tri1_t
BEGIN
  INSERT INTO msg VALUES (seq_tri.nextval, 'BEFORE INSERT tri2_t');
END;
/

INSERT INTO t VALUES (1, 1);

obclient> SELECT * FROM msg;
+----+----------------------+
| C1 | C2                   |
+----+----------------------+
|  1 | BEFORE INSERT tri1_t |
|  2 | BEFORE INSERT tri2_t |
+----+----------------------+
2 rows in set

```

示例 3：创建触发器，在更新表的特定列时记录到另一个表。

1. 创建触发器监视的原始数据表 `tbl1`。

   ```sql
   CREATE TABLE tbl1(col1 INT, col2 VARCHAR2(20));

   ```
 2. 向表 `tbl1` 中插入一条数据。

   ```sql
   INSERT INTO tbl1(col1, col2) VALUES(1,'A1');

   ```
 3. 创建触发器用于记录特定事件的日志表 `tbl2`。

   ```sql
   CREATE TABLE tbl2(col1 VARCHAR2(255));

   ```
 4. 将结束符改为 `//`。

   ```sql
   DELIMITER //

   ```
 5. 创建名为 `update_tbl1_trigger` 的触发器，用于监控表 `tbl1` 中 `col1` 和 `col2` 列的更新操作，并根据更新的情况向另一个表 `tbl2` 中插入相应的信息。该触发器的逻辑部分如下：

      - 当任何行的 `col1` 和 `col2` 被同时更新时，将插入一条信息：“Updating both col1 and col2!” 到表 `tbl2`。
      - 当仅更新 `col1` 时，将插入一条信息：“Updating only col1!” 到表 `tbl2`。
      - 当仅更新 `col2` 时，将插入一条信息：“Updating only col2!” 到表 `tbl2`。

   ```sql
   CREATE OR REPLACE TRIGGER update_tbl1_trigger
   BEFORE UPDATE OF col1, col2 ON tbl1
   FOR EACH ROW
   BEGIN
      IF UPDATING('col1') AND UPDATING('col2') THEN
         INSERT INTO tbl2(col1) VALUES ('Updating both col1 and col2!');
      END IF;
      IF UPDATING('col1') AND NOT UPDATING('col2') THEN
         INSERT INTO tbl2(col1) VALUES ('Updating only col1!');
      END IF;
      IF UPDATING('col2') AND NOT UPDATING('col1') THEN
         INSERT INTO tbl2(col1) VALUES ('Updating only col2!');
      END IF;
   END;
   //

   ```
 6. 将结束符还原为 `;`。

   ```sql
   DELIMITER ;

   ```
 7. 更新表 `tbl1` 中条件 `col1 = 1` 的行的 `col2` 列的值更新为 'A11'。

   ```sql
   UPDATE tbl1 SET col2 = 'A11' WHERE col1 = 1;

   ```
 8. 查看表 `tbl2`。

   ```sql
   SELECT * FROM tbl2;

   ```

   返回结果如下：

   ```shell
   +---------------------+
   | COL1                |
   +---------------------+
   | Updating only col2! |
   +---------------------+
   1 row in set

   ```

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