头歌实训之游标触发器

 各位看官好,我是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 ;

你可能感兴趣的:(数据库课后习题,android)