6.6 游标的使用

-- 游标(CURSOR)是 MySQL 中用于逐行处理结果集的数据库对象,相当于一个指针,指向结果集中的某一行数据。
-- 类比:游标就像图书馆的书架指针,你可以移动指针,一本一本地查看书籍。

-- 游标的使用分为四个步骤:

-- 步骤1:声明游标(必须在变量声明之后,处理程序声明之前)
sql
DECLARE 游标名 CURSOR FOR SELECT语句;
-- 步骤2:打开游标(执行SELECT语句,生成结果集)
sql
OPEN 游标名;
-- 步骤3:读取游标(将当前行数据存入变量,指针自动下移)
sql
FETCH 游标名 INTO 变量1, 变量2, ...;
-- 步骤4:关闭游标(释放资源,必须执行)
sql
CLOSE 游标名;
/* 语法
DECLARE 游标 CURSOR FOR 查询语句;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET 结束标记 = 1;

OPEN 游标;

-- 使用循环让游标处理多条数据
read_loop: LOOP
  FETCH 游标 INTO 变量;
  IF 结束标记 THEN LEAVE read_loop; END IF;
  -- 处理数据
END LOOP;

CLOSE 游标;
*/


/*
  使用句柄来对游标结束条件处理
当游标读取到结果集最后一行后,再次执行FETCH会触发NOT FOUND异常,
使用声明处理程序来捕获这个异常,设置结束标志
*/
-- 声明结束标志变量
sql
DECLARE done INT DEFAULT 0;
-- 声明处理程序:当NOT FOUND时,将done设为1
sql
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
-- 示例(遍历学生表输出姓名和性别)
sql
DROP PROCEDURE IF EXISTS proc_student_list;
DELIMITER //
CREATE PROCEDURE proc_student_list()
BEGIN
    -- 1. 声明变量
    DECLARE v_name VARCHAR(10);
    DECLARE v_sex VARCHAR(10);
    DECLARE done INT DEFAULT 0;
    -- 2. 声明游标
    DECLARE cur_student CURSOR FOR 
        SELECT Sname, Ssex FROM student;

    -- 3. 声明处理程序
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    -- 4. 打开游标
    OPEN cur_student;

    -- 5. 循环读取游标
    student_loop: LOOP
        -- 读取当前行数据
        FETCH cur_student INTO v_name, v_sex;

        -- 判断是否结束
        IF done = 1 THEN
            LEAVE student_loop;
        END IF;

        -- 处理数据:输出结果
        SELECT CONCAT('姓名:', v_name, ',性别:', v_sex) AS 学生信息;
    END LOOP student_loop;

    -- 6. 关闭游标
    CLOSE cur_student;
END //
DELIMITER ;

-- 调用存储过程
sql
CALL proc_student_list();
课堂练习
1、编写存储过程,遍历teacher表,输出所有教师的姓名和入职时间
2、编写存储过程,遍历sc表,统计每门课程的总分和平均分