mysql 循环和游标使用

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: mysql 循环和游标使用

循环

-- 求 1-n 的和
/*  while循环语法:
while 条件 DO
            循环体;
end while;
*/
 create procedure sum1(a int) 
 begin
     declare sum int default 0;  -- default 是指定该变量的默认值
     declare i int default 1;
   while i<=a DO -- 循环开始
      set sum=sum+i;
      set i=i+1;
   end while; -- 循环结束
   select sum;  -- 输出结果
 end;
 -- 执行存储过程
 call sum1(100);
 -- 删除存储过程
 drop procedure if exists sum1;
/*loop 循环语法:
  loop_name:loop
          if 条件 THEN -- 满足条件时离开循环
               leave loop_name;  -- 和 break 差不多都是结束训话
       end if;
  end loop;
  */
create procedure sums(a int)
begin
        declare sum int default 0;
        declare i int default 1;
        loop_name:loop -- 循环开始
            if i>a then 
                leave loop_name;  -- 判断条件成立则结束循环  好比java中的 boeak
            end if;
            set sum=sum+i;
            set i=i+1;
        end loop;  -- 循环结束
        select sum; -- 输出结果
end;
 -- 执行存储过程
call sums(100);
-- 删除存储过程
drop procedure if exists  sums;
/*repeat 循环语法
  repeat
      循环体
  until 条件 end repeat;
  */
-- 实例;
create procedure sum55(a int)
begin
    declare sum int default 0;
   declare i int default 1;
    repeat -- 循环开始
        set sum=sum+i;
        set i=i+1;
    until i>a end repeat; -- 循环结束
    select sum; -- 输出结果
end;
-- 执行存储过程
  call sum55(100);
-- 删除存储过程
drop procedure if exists sum55;

存储过程批量插入大量数据

CREATE DEFINER=`root`@`%` PROCEDURE `idata4`()
begin
  declare i int;    
  START TRANSACTION;  -- 开启事务
    set i=1;
    while(i<=100000)do
      insert into t2 values(i, i, i);
      set i=i+1;
    end while;
  COMMIT;   -- 提交事务
end

游标

DROP PROCEDURE IF EXISTS processorder;
CREATE PROCEDURE processorder()
BEGIN
  -- 定义游标
  DECLARE ordernumbers CURSOR
  FOR
  SELECT order_num FROM orders;
END;
DROP PROCEDURE IF EXISTS processorder;
CREATE PROCEDURE processorder()
BEGIN
    -- 定义局部变量
    DECLARE num INT;
    -- 定义游标
    DECLARE ordernumbers CURSOR
    FOR
    SELECT order_num FROM orders;
    -- 打开游标
    OPEN ordernumbers;
    -- 获取第一行数据
    FETCH ordernumbers INTO num;
    -- 查询结果
    SELECT num;
    -- 关闭游标
    CLOSE ordernumbers;
END;
CALL processorder();
DROP PROCEDURE IF EXISTS processorder;
CREATE PROCEDURE processorder()
BEGIN
  -- 定义局部变量
  DECLARE done BOOLEAN DEFAULT false;
  DECLARE num INT;
  -- 定义游标
  DECLARE ordernumbers CURSOR
  FOR
  SELECT order_num FROM orders;
  -- 定义CONTINUE HANDLER
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=true;
  -- 打开游标
  OPEN ordernumbers;
  -- 循环所有行
  REPEAT
    -- 获取第一行数据
    FETCH ordernumbers INTO num;
  -- 结束循环
  UNTIL done END REPEAT;
  -- 查询结果
  SELECT num;
  -- 关闭游标
  CLOSE ordernumbers;
END;
CALL processorder();
-- 临时表
CREATE TEMPORARY TABLE StgSummary(
 Name VARCHAR(50) NOT NULL,
 StgId INT NOT NULL DEFAULT 0
);
INSERT INTO StgSummary(Name,StgId) select '临时数据1',1;
INSERT INTO StgSummary(Name,StgId) select '临时数据2',2;
INSERT INTO StgSummary(Name,StgId) select '临时数据3',3;
INSERT INTO StgSummary(Name,StgId) select '临时数据4',4;
INSERT INTO StgSummary(Name,StgId) select '临时数据5',5;
INSERT INTO StgSummary(Name,StgId) select '临时数据6',6;
INSERT INTO StgSummary(Name,StgId) select '临时数据7',7;
INSERT INTO StgSummary(Name,StgId) select '临时数据8',8;
INSERT INTO StgSummary(Name,StgId) select '临时数据9',9;
INSERT INTO StgSummary(Name,StgId) select '临时数据10',10;
select * from StgSummary;
-- 不能用RENAME来重命名一个临时表,但是可以用ALTER TABLE代替
-- ALTER TABLE orig_name RENAME new_name;
-- 临时表使用完以后需要主动Drop掉
DROP TEMPORARY TABLE IF EXISTS StgTempTable;
CREATE TABLE StgSummary_bak(
 Name VARCHAR(50) NOT NULL,
 StgId INT NOT NULL DEFAULT 0
);
-- 存储过程
drop procedure if exists ry.pro_test;
delimiter $$
create procedure if not exists ry.pro_test()
begin
    -- 定义变量
    DECLARE done INT DEFAULT FALSE;
    DECLARE field_1 VARCHAR(20);
    DECLARE field_2 VARCHAR(20);
    -- 创建游标,并存储数据
    DECLARE cur_list CURSOR FOR SELECT StgId, name FROM StgSummary;
    -- 游标中的内容执行完后将done设置为true
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
    -- 打开游标
    OPEN cur_list;
    -- 执行循环
    read_loop : LOOP
        -- 取游标中的值
        FETCH cur_list INTO field_1, field_2;
        -- 判断是否结束循环,一定要放到FETCH之后,因为在fetch不到的时候才会设置done为true
        -- 如果放到fetch之前,先判断done,这个时候done的值还是之前的循环的值,因此就会导致循环一次
        IF done THEN
            LEAVE read_loop;
        END IF;
        --  执行SQL操作
        SET @sql_insert = CONCAT("insert into StgSummary_bak(StgId, name) VALUES ('", field_1, "','", field_2 ,"')");
        PREPARE sqlli FROM @sql_insert;
            EXECUTE  sqlli;
        COMMIT;
    END LOOP read_loop;
    -- 释放游标
    CLOSE cur_list;
end $$
delimiter ;
-- 调用存储过程
call pro_test()
select * from StgSummary_bak;

游标

  • 优点:游标是面向集合与面向行的设计思想之间的一种桥梁,因为游标是针对行操作的,所以对从数据库中 SELECT 查询得到的每一行可以进行分开的独立的相同或不同的操作,是一种分离的思想。可以满足对某个结果行进行特殊的操作。如基于游标位置的增删改查能力。
  • 缺点:
  • 速度较慢
  • 会产生死锁现象
  • 内存大


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
存储 关系型数据库 MySQL
轻松入门MySQL:揭秘MySQL游标,数据处理的神秘利器(16)
轻松入门MySQL:揭秘MySQL游标,数据处理的神秘利器(16)
141 0
|
6月前
|
存储 SQL 关系型数据库
20. Mysql 游标的定义和使用
20. Mysql 游标的定义和使用
62 1
|
6月前
|
存储 关系型数据库 MySQL
19. Mysql 循环语句
19. Mysql 循环语句
129 1
|
6月前
|
存储 SQL 关系型数据库
MySQL存储过程_触发器_游标——Baidu Comate
MySQL存储过程_触发器_游标——Baidu Comate
44 0
|
6月前
|
存储 SQL 关系型数据库
MySQL游标的创建与使用——Baidu Comate全文SQL-AI生成
MySQL游标的创建与使用——Baidu Comate全文SQL-AI生成
50 0
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库——存储过程-游标(介绍-声明游标、打开游标、获取游标记录、关闭游标,案例)
MySQL数据库——存储过程-游标(介绍-声明游标、打开游标、获取游标记录、关闭游标,案例)
271 0
|
6月前
|
存储 SQL 关系型数据库
MySQL数据库——存储过程-循环(while、repeat、loop)
MySQL数据库——存储过程-循环(while、repeat、loop)
1296 0
|
6月前
|
存储 关系型数据库 MySQL
mysql 存储过程游标 循环输出select 查询结果
mysql 存储过程游标 循环输出select 查询结果
124 0
|
7月前
|
关系型数据库 MySQL Java
使用shardingjdbc执行MySQL游标操作时报错
使用shardingjdbc执行MySQL游标操作时报错
193 3
|
7月前
|
关系型数据库 MySQL
Mysql基础第二十七天,使用游标
Mysql基础第二十七天,使用游标
34 0
Mysql基础第二十七天,使用游标