MySQL 游标(Cursor)详解:与存储过程的结合使用

在前一篇文章中【一文搞懂 MySQL 存储过程-CSDN博客】,我们已经系统讲解了 MySQL 存储过程 ,包括参数类型、变量、流程控制等内容。但在实际开发中,还有一类需求是单条 SQL 无法完成的 ------👉 需要对查询结果"一行一行地处理"。这样就用到了游标(Cursor)。

用一句话说:

游标是存储过程中,用来"逐行处理查询结果集"的机制。


目录

一、为什么需要游标?

二、什么是游标

三、游标的使用

[1. 声明游标](#1. 声明游标)

[2. 打开游标](#2. 打开游标)

[3. 读取游标数据](#3. 读取游标数据)

[4. 关闭游标](#4. 关闭游标)

[5. 声明句柄Handler](#5. 声明句柄Handler)

(1)句柄是什么

(2)句柄的标准写法

四、游标举例


一、为什么需要游标?

在MySQL中,大多数操作都是面向集合的,比如:

sql 复制代码
UPDATE emp SET sal = sal + 100 WHERE deptno = 10;

这样虽然写法高效,但是这种方式只能处理"清一色"的数据,面对多种不同类的记录,没有办法用单一规则实现完全更新。

也就是说,遇到下面的情况就需要用到游标了

  1. 不同记录需要不同的处理逻辑

  2. 需要在处理过程(存储过程/函数)中做判断、计算、日志记录

  3. 需要逐行读取并操作数据

二、什么是游标

游标是对查询结果集的一种控制结构,允许我们:

  • 一行一行地访问查询结果

  • 像"指针"一样向下移动

  • 配合循环逐条处理数据

这里可以把游标理解为指向查询结果集的"指针变量"。

三、游标的使用

1. 声明游标

这里要知道++游标一般在存储过程中声明++。

sql 复制代码
DECLARE 游标名 CURSOR FOR 查询语句;

2. 打开游标

sql 复制代码
OPEN 游标名;

打开游标后,MySQL 会执行游标中定义的查询语句,并生成结果集。

3. 读取游标数据

sql 复制代码
FETCH 游标名 INTO 存储变量1 [, 变量2...];

这里要注意:****(1)FETCH一次只读取一行;(2)存储变量个数必须和查询字段个数一致。

(3)读取≠输出,如果想输出结果的话,还要搭配select一起使用。

4. 关闭游标

sql 复制代码
CLOSE 游标名;

使用完游标之后需要关闭游标,用于释放内存和资源。

5. 声明句柄Handler

(1)句柄是什么

当游标读取到最后一行时,再次FETCH(读取)就会发生"找不到数据"的情况,如果不做处理,程序会直接报错。MySQL为了解决这个问题,MySQL提供了CONTINUE HANDLER(继续执行处理器)。

(2)句柄的标准写法

sql 复制代码
DECLARE done INT DEFAULT 0;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

这样就可以在发生"NOT found"时自动设置开关变量done为1。

四、游标举例

假设有一张表名为emp,现在要遍历emp表中的员工姓名ename,每次读取一条后输出。

sql 复制代码
DROP PROCEDURE IF EXISTS testcursor;

CREATE PROCEDURE testcursor()
BEGIN
    -- 1. 声明结束标志变量
    DECLARE done INT DEFAULT 0;

    -- 2. 声明接收字段的变量
    DECLARE emp_name VARCHAR(20);

    -- 3. 声明游标
    DECLARE mycursor CURSOR FOR
    SELECT ename FROM emp;

    -- 4. 声明句柄(当游标读不到数据时触发)
    DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET done = 1;

    -- 5. 打开游标
    OPEN mycursor;

    -- 6. 使用循环逐行读取游标数据
    WHILE done = 0 DO
        FETCH mycursor INTO emp_name;

        IF done = 0 THEN
            SELECT emp_name;
        END IF;
    END WHILE;

    CLOSE mycursor;
END;


call testcursor;

游标和句柄是相关联的,就体现在下面的过程中:

游标读不到数据 →→自动触发句柄 →→done自动设置为1 →→退出while循环

相关推荐
Web极客码2 小时前
宝塔面板后台突然显示“IO延迟非常高”
linux·服务器·数据库
IT教程资源D2 小时前
[N_160]基于springboot,vue校园论坛系统
mysql·vue·前后端分离·springboot校园论坛·校园论坛交流系统
zhihuaba2 小时前
构建一个基于命令行的待办事项应用
jvm·数据库·python
BullSmall2 小时前
ACID 中的一致性
数据库·oracle
Tangcan-2 小时前
【MySQL】 事务
数据库·mysql·adb
卡布叻_星星3 小时前
达梦数据库笔记之解决默认模式与当前表所属模式不匹配
数据库
xuefuhe3 小时前
PostgreSQL default_statistics_target参数详解
数据库·postgresql
码界奇点3 小时前
基于Django的超市管理系统设计与实现
数据库·python·django·sqlite·毕业设计·源代码管理
shejizuopin3 小时前
基于SSM的高校旧书交易系统的设计与实现(毕业论文)
java·mysql·毕业设计·论文·ssm·毕业论文·高校旧书交易系统的设计与实现