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循环

相关推荐
REDcker7 分钟前
OpenSSL:C 语言 TLS 客户端完整示例
c语言·网络·数据库
zly350014 分钟前
centos7 mysql 无法被远程连接
数据库·mysql
廿一夏14 分钟前
MySql的增删改查
数据库·mysql·dba
瀚高PG实验室16 分钟前
HGDB 4.5.8.8开启oracle兼容执行带聚合函数的SQL导致数据库进程被信号11杀死
数据库·sql·oracle·瀚高数据库
炘爚40 分钟前
日志系统整体设计步骤以及功能函数梳理
运维·服务器·数据库
_下雨天.40 分钟前
PostgreSQL日常维护
数据库·postgresql
神の愛40 分钟前
本地连接MySql数据库报错??
数据库·mysql
黑牛儿40 分钟前
MySQL 索引实战详解:为什么B+类型的索引查询更快
数据库·mysql
向上的车轮1 小时前
如何用DeepSeek定制大模型——智能Text-to-SQL专家系统
数据库·sql
一个有温度的技术博主1 小时前
Redis主从同步进阶:深入理解增量同步与性能优化
数据库·redis·性能优化