头歌实训之游标触发器

🌟 各位看官好,我是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))
BEGIN
    DECLARE 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 DO
        FETCH 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
BEGIN
    DELETE 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
BEGIN
    INSERT INTO user_logs (operation, operate_time, operate_id, operate_params)
    VALUES (
        'insert',
        NOW(),
        NEW.sno,
        CONCAT(
            '插入的数据内容为:sno=', NEW.sno, ', name=', NEW.snme
        )
    );
END##

DELIMITER ;
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值