概述

在数据库中,游标是个重要的概念,它提供了一种灵活的操作方式,可以让我们从数据结果集中每次提取一条数据记录进行操作。
在 SQL 中,游标是一种临时的数据库对象,可以指向存储在数据库表中的数据行指针。这里游标充当了指针的作用,我们可以通过操作游标来对数据行进行操作。

游标使用示例

假设我想用游标来扫描 heros 数据表中的数据行,然后累计最大生命值,那么该怎么做呢?

  1. CREATE PROCEDURE `calc_hp_max`()
  2. BEGIN
  3. -- 创建接收游标的变量
  4. DECLARE hp INT;
  5. -- 创建总数变量
  6. DECLARE hp_sum INT DEFAULT 0;
  7. -- 创建结束标志变量
  8. DECLARE done INT DEFAULT false;
  9. -- 定义游标
  10. DECLARE cur_hero CURSOR FOR SELECT hp_max FROM heros;
  11. -- 指定游标循环结束时的返回值
  12. DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
  13. OPEN cur_hero;
  14. read_loop:LOOP
  15. FETCH cur_hero INTO hp;
  16. -- 判断游标的循环是否结束
  17. IF done THEN
  18. LEAVE read_loop;
  19. END IF;
  20. SET hp_sum = hp_sum + hp;
  21. END LOOP;
  22. CLOSE cur_hero;
  23. SELECT hp_sum;
  24. END;

观察上述代码,我们先创建一个存储过程 calc_hp_max,然后在存储过程中定义游标 cur_hero,使用 FETCH 获取每一行的具体数值,然后赋值给变量 hp,再用变量 hp_sum 做累加求和,最后再输出 hp_sum。
当我们创建完成存储过程之后,可以调用该存储过程查询结果:

  1. CALL calc_hp_max();

image.png
可以看出,使用游标可以让我们对 SELECT 结果集中的每一行数据进行相同或者不同的操作,从而很精细化地管理结果集中的每一条数据。

游标的作用&使用场景

那么,游标究竟有什么实际的价值呢?它在什么场景下会使用呢?
其实,游标的作用主要在于对复杂数据的逐行处理。
例如,我们希望查询 10000 条记录,并对每条记录依次进行变更处理操作,这时,我们就可以通过游标来对数据进行依次的读取和处理。
虽然在处理某些复杂的数据情况下,使用游标可以更灵活,但同时也会带来一些性能问题,比如在使用游标的过程中,会对数据行进行加锁,这样在业务并发量大的时候,不仅会影响业务之间的效率,还会消耗系统资源,造成内存不足。