头歌实训之游标触发器
🌟 各位看官好,我是maomi_9526!
🌍 种一棵树最好是十年前,其次是现在!
🚀 今天来学习C语言的相关知识。
👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更多人哦
目录
5. 游标
5.1 声明游标
5.2 打开游标
5.3 取出数据
5.4 关闭游标
5.5 异常处理器(Handler)
5.6 游标的完整示例
6. 触发器
6.1 创建触发器
6.2 删除用户时同步删除其扩展表
6.3 查看、删除触发器
7. 注意事项与坑
触发器示例
5. 游标
在 MySQL 中,游标(Cursor)是一种用于遍历查询结果集的机制。游标允许你逐行处理查询结果,对于一些复杂的操作,比如逐行处理数据、进行复杂的计算等,游标非常有用。通常,游标用于存储过程中,在需要逐行处理结果集时使用。
5.1 声明游标
使用 DECLARE
语句声明游标。在声明游标时,需要指定游标基于的查询。
语法:
DECLARE 游标名 CURSOR FOR 查询语句;
5.2 打开游标
通过 OPEN
语句打开游标并执行查询。
语法:
OPEN 游标名;
5.3 取出数据
使用 FETCH
语句从游标中获取一行数据。
语法:
FETCH NEXT FROM 游标名 INTO 变量列表;
FETCH
会将游标当前指向的行的数据加载到指定的变量中。
5.4 关闭游标
当数据处理完毕后,使用 CLOSE
语句关闭游标。
语法:
CLOSE 游标名;
5.5 异常处理器(Handler)
在 MySQL 中,Handler(异常处理器)是用于处理存储过程中的异常和错误的机制。Handler 可以帮助在遇到特定条件(如查询结果为空、错误发生等)时,自动执行指定的操作,从而提高程序的健壮性和灵活性。
MySQL 提供了多种 Handler 类型,主要通过 DECLARE
语句声明。在存储过程中,Handler 用于捕获特定条件(如查询没有返回结果、触发错误等),并执行相应的操作。
Handler 机制的目的是:当遇到异常或特定条件时,不需要让存储过程中断,而是可以继续执行后续的逻辑。
Handler 的基本语法:
DECLARE handler_type HANDLER FOR condition_value action;
常见的 Handler 语句例子包括:
DECLARE EXIT HANDLER FOR SQLSTATE '02000'; -- 退出码退出
DECLARE EXIT HANDLER FOR NOT FOUND; -- 未找到退出
DECLARE EXIT HANDLER FOR SQLWARNING; -- SQL警告退出
5.6 游标的完整示例
以下是一个完整的游标示例,演示了如何使用游标在存储过程中逐行处理数据:
DELIMITER ##
CREATE PROCEDURE s10(IN p_sdept VARCHAR(10))
BEGINDECLARE c_snme VARCHAR(20);DECLARE c_sno VARCHAR(5);DECLARE c_birthday DATE;DECLARE c_name CURSOR FOR SELECT sno, snme, birthday FROM student WHERE p_sdept = sdept;DECLARE EXIT HANDLER FOR NOT FOUND CLOSE c_name;CREATE TABLE IF NOT EXISTS r1 (id VARCHAR(5),name VARCHAR(20),birthday DATE);OPEN c_name;WHILE TRUE DOFETCH c_name INTO c_sno, c_snme, c_birthday;INSERT INTO r1 VALUES(c_sno, c_snme, c_birthday);END WHILE;CLOSE c_name;
END ##
DELIMITER ;
6. 触发器
触发器(Trigger)是 MySQL 中的一种机制,允许在数据库表中发生特定事件(如插入、更新或删除)时自动执行一系列操作。
6.1 创建触发器
创建触发器时,首先使用 DELIMITER
临时改变语句分隔符,以便在触发器体内使用分号。然后,通过 CREATE TRIGGER
语句创建触发器。
语法:
DELIMITER $$ -- 临时换分隔符,避免碰到触发器体内的分号CREATE TRIGGER 触发器名
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON 表名
FOR EACH ROW
BEGIN-- 触发器体:可写多条语句-- 可用 NEW.列名 访问“新值”-- 可用 OLD.列名 访问“旧值”(对于 INSERT 没旧值,DELETE 没新值)
END$$DELIMITER ; -- 恢复默认分隔符
6.2 删除用户时同步删除其扩展表
以下触发器示例在删除用户时,同时删除用户在 user_profile
表中的扩展信息:
DELIMITER $$CREATE TRIGGER user_bd_cleanup
BEFORE DELETE ON user
FOR EACH ROW
BEGINDELETE FROM user_profile WHERE uid = OLD.uid;
END$$DELIMITER ;
6.3 查看、删除触发器
-
查看当前库所有触发器:
SHOW TRIGGERS\G
-
查看某触发器的创建语句:
SHOW CREATE TRIGGER student_ai_log\G
-
删除触发器:
DROP TRIGGER IF EXISTS student_ai_log;
7. 注意事项与坑
主题 | 说明 |
---|---|
权限 | 需要 TRIGGER 权限(或 SUPER )才能创建/删除触发器。 |
单表同事件多触发器 | MySQL 8.0 允许同一“事件+时机”创建多个触发器,但 5.7 及更早版本只允许一个。 |
递归触发 | 触发器里对同一张表再执行 INSERT/UPDATE/DELETE 会再次触发,谨防无限递归。 |
事务 | 触发器在当前事务中执行,若触发器报错,整个外层语句会回滚。 |
NEW/OLD 只读限制 | BEFORE UPDATE 中可修改 NEW.xxx 来影响即将写入的值;其他场景 NEW/OLD 均只读。 |
不支持 COMMIT/ROLLBACK | 触发器体内禁止显式提交或回滚。 |
触发器示例
DELIMITER ##CREATE TRIGGER tb_user_insert_trigger
AFTER INSERT ON student
FOR EACH ROW
BEGININSERT INTO user_logs (operation, operate_time, operate_id, operate_params)VALUES ('insert',NOW(),NEW.sno,CONCAT('插入的数据内容为:sno=', NEW.sno, ', name=', NEW.snme));
END##DELIMITER ;