基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
创建 DML 触发器
更新时间:2023-07-18 17:25:58
创建触发器
您可以使用 CREATE TRIGGER 语句创建触发器。
创建触发器的用户需要具备以下权限:
当前触发器关联的表的权限,包括
SELECT、INSERT、UPDATE、DELETE等权限。触发器权限,即
CREATE TRIGGER权限。触发器激活后要执行的语句的权限。
创建触发器的 SQL 语法如下:
CREATE
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
语法说明:
触发器名称
trigger_name必须保持唯一。tbl_name表示建立触发器的表名,即在哪张表上建立触发器。BEFORE或AFTER表示触发动作的时间,即触发器将在每一行插入到表中之前还是之后激活。INSERT、UPDATE或DELETE表示触发事件,即激活触发器的操作类型。FOR EACH ROW用于定义触发器的主体,每次触发器激活时就会执行该语句,对于受触发事件影响的每一行都会执行一次。
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 操作,且触发器充当累加器,将插入到表的列的值求和。
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 语句的语法为:
BEGIN
[statement_list]
END
其中,statement_list 表示一个或多个语句的列表,列表内的每条语句都必须使用分号(;)结尾。由于在 SQL 语句中,分号(;)是语句结束的标识符,遇到分号表示该段语句已经结束,系统就会开始执行该段语句,最终导致在执行过程中,解释器因为找不到与 BEGIN 匹配的 END而报错。为了避免发生此类错误,可以使用 DELIMITER 命令来修改语句结束符。
DELIMITER 命令示例如下:
DELIMITER new_delimiter
其中,new_delimiter 可以设置为 1 个或多个长度的符号,默认为分号(;),您可以将其修改为其他符号,例如 #。
添加 DELIMITER 命令后, DELIMITER 命令后的语句再使用分号则不会报错,直到遇到设置的结束符(#),才认为该语句结束。
注意
使用
DELIMITER命令修改结束符后,待语句执行结束,请务必将结束符修改为默认符号分号(;)。
示例如下:
obclient>CREATE TABLE test (user_id INT, user_num DECIMAL(10,2));
Query OK, 0 rows affected
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 模式的触发器有以下使用限制:
对于同一个表,不能有多个触发器具备相同的触发事件和触发动作的时间。
只能在永久表上创建触发器,不能对临时表创建触发器。
触发器不能使用
CALL语句调用将数据返回给客户端或使用动态 SQL 的存储过程,但是允许存储过程或者函数通过OUT或者 INOUT类型的参数将数据返回触发器。触发器中不能使用开启或结束事务的语句段,例如,开始事务(
START TRANSACTION)、提交事务(COMMIT)或回滚事务(ROLLBACK),但是可以回滚到一个保存点,即 Savepoint 是允许的,因为回滚到保存点不会结束事务。外键不会激活触发器。
触发器中不允许返回值,因此触发器中不能有返回语句,如果需要立即停止一个触发器,则需要使用
LEAVE语句。