赞
踩
最近项目中需要迁移数据,对旧表A 的每一行记录处理后插入 新表B。 Google一下,发现 MySQL Cursor 适合这种场景,上篇文章介绍了 handler,那么本篇就一起看下 Cursor 是什么吧!
本文基于 MySQL 8.0
我们来看看 ChatGPT 是怎么理解MySQL Cursor 的吧:
我:MySQL Cursor 是什么?
ChatGPT:MySQL 中的 Cursor 是一种用于在存储过程、函数等数据库对象中,按照一定顺序依次遍历结果集中每一条记录的机制。具体地说,使用 Cursor 可以将结果集中的记录一条一条地处理,每次处理一条记录,直到处理完所有记录。
Cursor 的使用非常灵活,可以用于在数据库对象中对结果集进行迭代,执行某些计算、条件判断等操作,在不同记录之间进行状态转移等。可以使用 Cursor 访问结果集的每一行、每一列,并对结果集中的数据进行修改、删除、插入等操作。
需要注意的是,使用 Cursor 需要谨慎,因为 Cursor 首先会将所有记录都读入到内存中,开销较大,而且 Cursor 可能会导致并发性和性能问题。除非必要,一般情况下不建议滥用 Cursor。
Cursor 就是游标,可以理解为 Java 集合迭代器的游标,或者数组的下标。在存储过程中对查询的数据进行处理时,由于 Select 返回的是个数据集,无法处理第一行、下一行、前十行的数据,除非每次修改 where 条件获得想要的那一条记录,而 Cursor 可以很方便的处理这种情况。
MySQL游标是只读的,不可滚动且不敏感的。
Cursor 的使用分为如下四步:
DECLARE cursor_name CURSOR FOR select_statement
注意:
OPEN cursor_name
FETCH cursor_name INTO var_name [, var_name] ...
注意:
使用 fetch 获取游标中 Select 语句的下一条记录,并将游标前进一步。如果查询到数据,就将每列对应的值赋值给相应变量;如果已经到了数据集末尾,没有数据可以获取了,会产生一个值为 '02000'
的 SQLSTATE (NOT FOUND),此时可以声明一个 handler 来处理这种情况。
如果我们在一个代码块中有多个游标,那么一个游标 fetch 时如果产生 NOT FOUND,handler 的触发可能会对另一个游标产生影响。如果想避免这种影响,可以在多个 BEGIG…END 代码块中分别声明各自的handler,然后再操作游标,保证互不影响。
CLOSE cursor_name
如下示例中,我们声明了两个游标 cur1 和 cur2,分别查询 id、data 和 i 字段;还声明了一个 CONTINUE handler,当其中一个游标访问到数据集末尾时,设置变量 done 为 TRUE,用于控制循环退出。
其中几个注意点:
CREATE PROCEDURE curdemo() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE a CHAR(16); DECLARE b, c INT; DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur1; OPEN cur2; read_loop: LOOP FETCH cur1 INTO a, b; FETCH cur2 INTO c; IF done THEN LEAVE read_loop; END IF; IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END LOOP; CLOSE cur1; CLOSE cur2; END;
本篇文章介绍了 MySQL Cursor 的使用方式,主要分为四步:声明、开启、获取、关闭,比较适合在刷数据或迁移数据时使用。
微信公众号:CodePlayer
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。