基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
CREATE TRIGGER
更新时间:2026-07-15 22:01:31
CREATE TRIGGER 语句用于创建或替换数据库触发器。
当发生指定条件时,数据库将自动运行触发器。
功能适用性
该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版仅提供 MySQL 模式。
前提条件
要在用户自己的 Schema 或 Schema 的表上创建触发器,必须具有 CREATE TRIGGER 的系统权限。
要在其他用户的 Schema(schema.SCHEMA)中创建触发器,必须具有 CREATE ANY TRIGGER 的系统权限。
如果触发器执行 SQL 语句或调用存储过程或函数,则触发器的所有者必须具有执行这些操作所需的权限。这些权限必须直接授予使用者,而不是通过角色获得。
语法
create_trigger 的语法如下:
CREATE [OR REPLACE] TRIGGER
plsql_trigger_source
BEGIN
triggered_action;
END;
其中:
plsql_trigger_source的语法如下:[schema.] trigger_name { simple_dml_trigger | instead_of_dml_trigger | trigger_ordering_clause }simple_dml_trigger的语法如下:{ BEFORE | AFTER } dml_event_clause [ referencing_clause ] [ FOR EACH ROW ] [ ENABLE | DISABLE ] [ WHEN ( condition ) ] trigger_bodyinstead_of_dml_trigger的语法如下:INSTEAD OF { DELETE | INSERT | UPDATE } [ OR { DELETE | INSERT | UPDATE } ]... ON [ schema. ] view [ referencing_clause ] [ FOR EACH ROW ] [ ENABLE | DISABLE ] trigger_bodytrigger_ordering_clause的语法如下:{ FOLLOWS | PRECEDES } [ schmema.] trigger_name [ , [ schmema.] trigger_name ]...dml_event_clause的语法如下:{ DELETE | INSERT | UPDATE [ OF column [, column ]... ] } [ OR { DELETE | INSERT | UPDATE [ OF column [, column]... ] }...] ON [ schema.] { table | view }referencing_clause的语法如下:REFERENCING { OLD [ AS ] old | NEW [ AS ] new | PARENT [ AS ] parent }..trigger_body的语法如下:{ 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。
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 之后执行。
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:创建触发器,在更新表的特定列时记录到另一个表。
创建触发器监视的原始数据表
tbl1。CREATE TABLE tbl1(col1 INT, col2 VARCHAR2(20));向表
tbl1中插入一条数据。INSERT INTO tbl1(col1, col2) VALUES(1,'A1');创建触发器用于记录特定事件的日志表
tbl2。CREATE TABLE tbl2(col1 VARCHAR2(255));将结束符改为
//。DELIMITER //创建名为
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。
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; //- 当任何行的
将结束符还原为
;。DELIMITER ;更新表
tbl1中条件col1 = 1的行的col2列的值更新为 'A11'。UPDATE tbl1 SET col2 = 'A11' WHERE col1 = 1;查看表
tbl2。SELECT * FROM tbl2;返回结果如下:
+---------------------+ | COL1 | +---------------------+ | Updating only col2! | +---------------------+ 1 row in set