游标是面向过程的编程方式,通过逐条处理数据的方式,让 SQL 这种面向集合的语言有了面向过程开发的能力。
游标的使用
定义游标
MySQL:
DECLARE cursor_name CURSOR FOR select_statement
如果是用 Oracle 或者 PostgreSQL:
DECLARE cursor_name CURSOR IS select_statement
例如
DECLARE stu_names CURSOR FOR SELECT name FROM students;
打开游标
OPEN cursor_name
想要使用游标,必须先打开游标。打开游标的时候 SELECT 语句的查询结果集就会送到游标工作区。
从游标中取得数据
FETCH cursor_name INTO var_name ...
使用 cursor_name 这个游标来读取当前行,将数据保存到 var_name 这个变量中,游标指针指到下一行。
如果游标读取的数据行有多个列名,则在 INTO 关键字后面赋值给多个变量名即可。
关闭游标
CLOSE cursor_name
释放游标
DEALLOCATE cursor_namec
案例
CREATE PROCEDURE `calc_hp_max`()
BEGIN
-- 创建接收游标的变量
DECLARE hp INT;
-- 创建总数变量
DECLARE hp_sum INT DEFAULT 0;
-- 创建结束标志变量
DECLARE done INT DEFAULT false;
-- 定义游标
DECLARE cur_hero CURSOR FOR SELECT hp_max FROM heros;
-- 指定游标循环结束时的返回值
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
OPEN cur_hero;
read_loop:LOOP
FETCH cur_hero INTO hp;
-- 判断游标的循环是否结束
IF done THEN
LEAVE read_loop;
END IF;
SET hp_sum = hp_sum + hp;
END LOOP;
CLOSE cur_hero;
DEALLOCATE cur_hero;
SELECT hp_sum;
END
游标的缺点
会带来一些性能问题,比如在使用游标的过程中,会对数据行进行加锁,这样在业务并发量大的时候,不仅会影响业务之间的效率,还会消耗系统资源,造成内存不足,这是因为游标是在内存中进行的处理。如果有游标的替代方案,我们可以采用替代方案。
此文章为3月Day6学习笔记,内容来源于极客时间《16丨游标:当我们需要逐条处理数据时,该怎么做? (geekbang.org)》