前言:新项目需要添加 删除用户在系统内的所有痕迹、新增排行榜及获取用户的排名 两个功能

因为排行榜模块相对而言比较有代表性,故此处仅使用排行榜模块,

游标的定义

用于临时存储一个查询返回的多行数据(结果集,类似于java的jdbc连接返回的ResultSet集合),通过遍历游标,可以逐行访问处理该结果集的数据.

游标的使用方式:  声明---打开--读取---关闭

游标的语法

游标声明:

CURSOR 游标名(参数列表)  IS 查询语句;

游标的打开:

OPEN 游标名

游标的取值:

FETCH 游标名 INTO 变量列表

游标的关闭:

CLOSE 游标名

游标的属性

 

游标的属性 返回值类型 说明
%ROWCOUNT 整型 获取FETCH语句返回的数据行数
%FOUND 布尔型 最近的FETCH语句返回一行数据则为真,否则为加
%NOTFOUND 布尔型 与%FOUND属性返回值相反
%ISOPEN 布尔型 游标已经打开时值为真,否则为假

以上内容摘抄自:https://www.cnblogs.com/tanlei-sxs/p/9807982.html

首先,写一个存储过程的基础语法(参考上一篇文章):https://www.cnblogs.com/fuhui-study-footprint/p/11975812.html

之后将游标的语法搬过来融合

-- 插入科目一数据
drop procedure p_ranking_subject1;
CREATE PROCEDURE `p_ranking_subject1`()
begin
     -- 声明接收游标返回的变量
	DECLARE user_id1 INT;
	DECLARE score1 INT;
	DECLARE test_type1 INT;
	DECLARE test_time1 INT;
	-- 声明排名变量
	DECLARE ranking_no int DEFAULT 0;
     -- 声明游标是否是最后一页变量
	DECLARE done int DEFAULT 0;
	

     -- 此处声明游标,获取排名的信息,将结果集,放入ranking游标
	DECLARE ranking CURSOR FOR select user_id,score,test_type,test_time from t_user_test where test_type = 1 group by user_id order by score desc, test_time asc, create_time asc;
     -- 若没有数据返回,程序继续,并将变量IS_FOUND设为0 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
     -- 此处执行一次,排名+1,因为查询语句已经是根据排名查询出来的,所以按照顺序设置排名就可以了 set ranking_no = ranking_no + 1; -- 打开游标 open ranking; -- 将游标中的值赋值给变量,注意:变量名不要和返回的列名同名,变量顺序要和sql结果列的顺序一致 fetch ranking into user_id1, score1, test_type1, test_time1; -- 当s不等于1,也就是未遍历完时,会一直循环 while done <> 1 do -- 执行业务逻辑 insert into t_ranking(`no`,`user_id`,`score`,`test_type`,`test_time`, `create_time`) values (ranking_no, user_id1, score1, test_type1, test_time1, now()); set ranking_no = ranking_no + 1; fetch ranking into user_id1, score1, test_type1, test_time1; -- 当s等于1时表明遍历以完成,退出循环 end while; -- 关闭游标 close ranking; end;
-- 执行存储过程 call p_ranking_subject1();

 上面存储过程是我的逻辑,很low勉强算是达到目的,如果有大神看出有更好的方法,非常期望您能给予指点!

在写这篇文章的时候,又看了几篇文章,其中有双游标的使用,例:

CREATE PROCEDURE procedureDemo()
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;

其中大部分文章对游标的循环用的都是loop,loop也是mysql循环的一种方式,具体参考:https://www.cnblogs.com/Luouy/p/7301360.html?utm_source=itdadao&utm_medium=referral

posted on 2019-12-03 12:02  浅灰色的记忆  阅读(1323)  评论(0编辑  收藏  举报