我有一个查询结果集(暂且标记它为t_tmp),如下所示:

    MySQL游标 存储过程 - 图1

    另外,有一张原始表airport,它的last_people列是空的。

    MySQL游标 存储过程 - 图2

    现在我想将我查询出来的结果集t_tmp中的last_people列填充到airportlast_people列。

    由于需要一行一行对应的插入,所以想到了mysql游标功能。下面是存储过程代码:

    1. CREATE PROCEDURE fillLastPeople()
    2. BEGIN
    3. # 循环控制变量
    4. DECLARE done BOOLEAN DEFAULT 0;
    5. DECLARE tmp_city varchar(255);
    6. DECLARE tmp_current_people int;
    7. DECLARE tmp_last_people int;
    8. #定义游标
    9. DECLARE t_index cursor FOR
    10. SELECT a.city,a.current_people,b.last_people
    11. FROM
    12. (SELECT city,current_people from airport
    13. where content_date = '2019'
    14. ) AS a
    15. INNER JOIN
    16. (SELECT city,current_people as last_people from airport
    17. where content_date = '2018'
    18. ) as b
    19. on a.city = b.city;
    20. #循环控制变量结束状态
    21. DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
    22. #打开游标
    23. open t_index;
    24. REPEAT
    25. #捕获游标--对应上面声明时select语句有几列就into几列,并且保证类型正确
    26. FETCH t_index into tmp_city,tmp_current_people,tmp_last_people;
    27. #这里进行更新操作
    28. update airport set last_people=tmp_last_people where city=tmp_city and content_date='2019';
    29. UNTIL done END REPEAT;
    30. #关闭游标
    31. close t_index;
    32. END;

    在mysql控制台输入上面这段存储过程代码前,需要输入delimiter // 保证;不会作为语句结束标记。

    1、游标声明语法:

    DECLARE 游标名称 cursor FOR select

    2、 打开、关闭、使用游标

    open 游标名称; close 游标名称; fetch 游标名称 into *

    3、控制循环

    DECLARE done BOOLEAN DEFAULT 0; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; REPEAT 具体逻辑 UNTIL done END REPEAT;

    4、使用

    delimiter ; call fillLastPeople(); //如果需要删除 drop PROCEDURE if EXISTS fillLastPeople;

    参考文章:

    https://blog.csdn.net/u010003835/article/details/50716610

    https://segmentfault.com/a/1190000005807737