MySQL 游标的使用

MySQL 游标

游标的特性

  • 不敏感:数据库可以选择不复制结果集

  • 只读

  • 不滚动:游标只能向一方向前进,并且不可以跳过任何一行数据

游标的优点

  • 游标是针对行操作的,对从数据库中 select 查询得到的结果集的 每一行可以

    进行分开的独立的相同或者不相同的操作,是一种分离的思想。

游标的缺点

  • 性能不高

  • 只能一行一行操作

  • 使用游标会产生死锁,造成内存开销大

游标的适用场景

  • 存储过程

  • 函数

  • 触发器

  • 事件

游标的操作

1、游标的定义

DECLARE 光标名称 CURSOR FOR 查询语法

declare cursor_name cursor for select_statement

2、打开游标

OPEN 光标名称

open cursor_name

3、取游标中的数据

FETCH 光标名称 INFO var_name [,var_name ].....

fetch cursor_name info var_name

4、关闭游标

CLOSE curso_name;

close 光标名称

5、释放游标

DEALLOCATE 光标名称

deallocate cursor_name;

游标示例
create table student(
    stuId int primary key auto_increment,
    stuName varchar(20),
    stuSex varchar(2),
    stuAge int
)default charset=utf8;
​
insert into student(stuName,stuSex,stuAge) values
('小明','男',20),
('小花','女',19),
('大赤','男',20),
('可乐','男',19),
('莹莹','女',19);

普通案例

delimiter //
create procedure p1()
begin
    declare id int;
    declare name varchar(100) character set utf8;
    declare done int default 0;
    -- 声明游标
    declare mc cursor for select stuId,stuName from student where stuAge >19;
    declare continue handler for not found set done = 1;
    -- 打开游标
    open mc;
    -- 获取结果
    fetch mc into id,name;
    -- 这里是为了显示获取结果
    select id,name;
    -- 关闭游标
    close mc;
end //
delimiter ;

试使用 三种方式 使用游标创建一个存储过程,统计年龄大于19的记录的数量

Loop循环
-- 定义语法结束符号
delimiter //
-- 创建一个 名称为 p2 的存储过程
create procedure p2()
begin
    -- 创建 用于接收游标值的变量
    declare id,age,total int;
    -- 注意 接收游标值为中文时 需要 给变量 指定 字符集为utf8
    declare name,sex varchar(20) character set utf8;
    
    -- 游标结束的标志
    declare done int default 0;
    -- 声明游标
    declare cur cursor for select stuId,stuName,stuSex,stuAge from student where stuAge > 19;
    -- 指定游标循环结束时的返回值 
    declare continue handler for not found set done =1;
    -- 打开游标
    open cur;
    
    -- 初始化 变量
    set total = 0;
    
    -- loop 循环
    xxx:loop
        -- 根据游标当前指向的一条数据  
        fetch cur into id,name,sex,age;
        -- 当 游标的返回值为 1 时 退出 loop循环 
        if done = 1 then
            leave xxx;
        end if;
        -- 累计
        set total = total + 1;
    end loop;
    -- 关闭游标
    close cur;
    -- 输出 累计的结果
    select total;
end //
delimiter ;
while 循delimiter /-- 创建一个 名称为 p3 的存储过程create procedure p3()
delimiter //
-- 创建一个 名称为 p3 的存储过程
create procedure p3()
begin
    -- 创建 用于接收游标值的变量
    declare id,age,total int;
    -- 注意 接收游标值为中文时 需要 给变量 指定 字符集为utf8
    declare name,sex varchar(20) character set utf8;
    -- 游标结束的标志
    declare done int default 0;
    -- 声明游标
    declare cur cursor for select stuId,stuName,stuSex,stuAge from student where stuAge > 19;
    -- 指定游标循环结束时的返回值 
    declare continue handler for not found set done = 1;
    -- 打开游标
    open cur;
    
    -- 初始化 变量
    set total = 0;
    
    -- while 循环
    while done != 1 do
        fetch cur into id,name,sex,age;
          if done != 1 then
             set total = total + 1;
          end if;    
    end while;
    -- 关闭游标
    close cur;
    -- 输出 累计的结果
    select total;
end //
delimiter ;
repeat 循环
delimiter //
-- 创建一个 名称为 p3 的存储过程
create procedure p3()
begin
    -- 创建 用于接收游标值的变量
    declare id,age,total int;
    -- 注意 接收游标值为中文时 需要 给变量 指定 字符集为utf8
    declare name,sex varchar(20) character set utf8;
    -- 游标结束的标志
    declare done int default 0;
    -- 声明游标
    declare cur cursor for select stuId,stuName,stuSex,stuAge from student where stuAge > 19;
    -- 指定游标循环结束时的返回值 
    declare continue handler for not found set done = 1;
    -- 打开游标
    open cur;
    
    -- 初始化 变量
    set total = 0;
    
    -- repeat 循环
    repeat
        fetch cur into id,name,sex,age;
           if done != 1 then
              set total = total + 1;
           end if;
        until done = 1
    end repeat;
    -- 关闭游标
    close cur;
    -- 输出 累计的结果
    select total;
end //
delimiter ;

 

 while 循环 repeat 循环 不知道 是不是理解错了 会多循环一次…(还是游标多走了一次…)  ---->    进行累加计算时,先判断游标的结束标志(done) 是否是为1

posted @ 2019-04-10 17:08  追梦滴小蜗牛  阅读(45280)  评论(8编辑  收藏  举报