加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

mysql游标的作用指什么

发布时间:2023-06-07 13:43:07 所属栏目:MySql教程 来源:
导读:给大家分享一下mysql游标的作用是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
给大家分享一下mysql游标的作用是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
 
在mysql中,游标有指针的作用,主要用于对查询数据库所返回的记录结果集进行遍历,以便进行相应的操作。 游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。关系数据库管理系统实质是面向集合的,在MySQL中并没有一种描述表中单一记录的表达形式,除非使用WHERE子句来限制只有一条记录被选中;所以有时必须借助于游标来进行单条记录的数据处理。
 
本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。
 
MySQL游标(Cursor)
 
游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。
 
游标充当指针的作用。
 
尽管游标能遍历结果中的所有行,但他一次只指向一行。
 
游标的作用就是用于对查询数据库所返回的记录进行遍历,以便进行相应的操作。
 
关系数据库管理系统实质是面向集合的,在 MySQL 中并没有一种描述表中单一记录的表达形式,除非使用 WHERE 子句来限制只有一条记录被选中。所以有时我们必须借助于游标来进行单条记录的数据处理。
 
一般通过游标定位到结果集的某一行进行数据修改。
 
游标的用法
 
1、声明一个游标: declare 游标名称 CURSOR for table;(这里的table可以是你查询出来的任意集合)
 
2、打开定义的游标:open 游标名称;
 
3、获得下一行数据:FETCH  游标名称 into testrangeid,versionid;
 
4、需要执行的语句(增删改查):这里视具体情况而定
 
5、释放游标:CLOSE 游标名称;
 
注:mysql存储过程每一句后面必须用;结尾,使用的临时字段需要在定义游标之前进行声明。
 
实例
 
-  BEGIN  
 
  --定义变量  declare testrangeid BIGINT;  
 
declare versionid BIGINT;   
 
declare done int;  
 
--创建游标,并存储数据  declare cur_test CURSOR for   
 
   select id as testrangeid,version_id as versionid from tp_testrange;  
 
--游标中的内容执行完后将done设置为1  
 
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;   
 
--打开游标  open cur_test;  
 
--执行循环    posLoop:LOOP  
 
--判断是否结束循环  
 
        IF done=1 THEN    
 
      LEAVE posLoop;  
 
    END IF;   
 
--取游标中的值  
 
    FETCH  cur_test into testrangeid,versionid;  
 
--执行更新操作  
 
    update tp_data_execute set version_id=versionid where testrange_id = testrangeid;  
 
  END LOOP posLoop;  
 
--释放游标  CLOSE cur_test;  

END  -
 
例子2:
 
我们现在要用存储过程做一个功能,统计iphone的总库存是多少,并把总数输出到控制台。
 
--在windows系统中写存储过程时,如果需要使用declare声明变量,需要添加这个关键字,否则会报错。  delimiter //  drop procedure if exists StatisticStore;  
 
CREATE PROCEDURE StatisticStore()  
 
BEGIN  
 
    --创建接收游标数据的变量  
 
    declare c int;  
 
    declare n varchar(20);  
 
    --创建总数变量  
 
    declare total int default 0;  
 
    --创建结束标志变量  
 
    declare done int default false;  
 
    --创建游标  
 
    declare cur cursor for select name,count from store where name = 'iphone';  
 
    --指定游标循环结束时的返回值  
 
    declare continue HANDLER for not found set done = true;  
 
    --设置初始值  
 
    set total = 0;  
 
    --打开游标  
 
    open cur;  
 
    --开始循环游标里的数据      read_loop:loop  
 
    --根据游标当前指向的一条数据  
 
    fetch cur into n,c;  
 
    --判断游标的循环是否结束  
 
    if done then  
 
        leave read_loop;    --跳出游标循环  
 
    end if;  
 
    --获取一条数据时,将count值进行累加操作,这里可以做任意你想做的操作,  
 
    set total = total + c;  
 
    --结束游标循环  
 
    end loop;  
 
    --关闭游标  
 
    close cur;  

    --输出结果  
 
    select total;  
 
END;  
 
--调用存储过程  call StatisticStore();
 
fetch是获取游标当前指向的数据行,并将指针指向下一行,当游标已经指向最后一行时继续执行会造成游标溢出。
 
使用loop循环游标时,他本身是不会监控是否到最后一条数据了,像下面代码这种写法,就会造成死循环;
 
read_loop:loop  
 
fetch cur into n,c;  
 
set total = total+c;  
 
end loop;
 
在MySql中,造成游标溢出时会引发mysql预定义的NOT FOUND错误,所以在上面使用下面的代码指定了当引发not found错误时定义一个continue 的事件,指定这个事件发生时修改done变量的值。
 
declare continue HANDLER for not found set done = true;
 
所以在循环时加上了下面这句代码:
 
--判断游标的循环是否结束  if done then  
 
    leave read_loop;    --跳出游标循环  end if;
 
如果done的值是true,就结束循环。继续执行下面的代码
 
使用方式
 
游标有三种使用方式:
 
第一种就是上面的实现,使用loop循环;
 
第二种方式如下,使用while循环:
 
drop procedure if exists StatisticStore1;  
 
CREATE PROCEDURE StatisticStore1()  
 
BEGIN  
 
    declare c int;  
 
    declare n varchar(20);  
 
    declare total int default 0;  
 
    declare done int default false;  
 
    declare cur cursor for select name,count from store where name = 'iphone';  
 
    declare continue HANDLER for not found set done = true;  
 
    set total = 0;  
 
    open cur;  
 
    fetch cur into n,c;  
 
    while(not done) do  
 
        set total = total + c;  
 
        fetch cur into n,c;  
 
    end while;  

    close cur;  
 
    select total;  
 
END;  
 
  
 
call StatisticStore1();
 
第三种方式是使用repeat执行:
 
drop procedure if exists StatisticStore2;  
 
CREATE PROCEDURE StatisticStore2()  
 
BEGIN  
 
    declare c int;  
 
    declare n varchar(20);  
 
    declare total int default 0;  
 
    declare done int default false;  
 
    declare cur cursor for select name,count from store where name = 'iphone';  
 
    declare continue HANDLER for not found set done = true;  
 
    set total = 0;  
 
    open cur;  
 
    repeat  
 
    fetch cur into n,c;  
 
    if not done then  
 
        set total = total + c;  
 
    end if;  
 
    until done end repeat;  
 
    close cur;  
 
    select total;  
 
END;  
 
  
 
call StatisticStore2();
 
游标嵌套
 
在mysql中,每个begin end 块都是一个独立的scope区域,由于MySql中同一个error的事件只能定义一次,如果多定义的话在编译时会提示Duplicate handler declared in the same block。
 
drop procedure if exists StatisticStore3;  
 
CREATE PROCEDURE StatisticStore3()  
 
BEGIN  
 
    declare _n varchar(20);  
 
    declare done int default false;  
 
    declare cur cursor for select name from store group by name;  
 
    declare continue HANDLER for not found set done = true;  
 
    open cur;  
 
    read_loop:loop  
 
    fetch cur into _n;  
 
    if done then  
 
        leave read_loop;  
 
    end if;  
 
    begin  
 
        declare c int;  
 
        declare n varchar(20);  
 
        declare total int default 0;  
 
        declare done int default false;  
 
        declare cur cursor for select name,count from store where name = 'iphone';  
 
        declare continue HANDLER for not found set done = true;  
 
        set total = 0;  
 
        open cur;  
 
        iphone_loop:loop  
 
        fetch cur into n,c;  
 
        if done then  
 
            leave iphone_loop;  
 
        end if;  
 
        set total = total + c;  
 
        end loop;  
 
        close cur;  
 
        select _n,n,total;  
 
    end;  
 
    begin  
 
            declare c int;  
 
            declare n varchar(20);  
 
            declare total int default 0;  
 
            declare done int default false;  
 
            declare cur cursor for select name,count from store where name = 'android';  
 
            declare continue HANDLER for not found set done = true;  
 
            set total = 0;  
 
            open cur;  
 
            android_loop:loop  
 
            fetch cur into n,c;  
 
            if done then  
 
                leave android_loop;  
 
            end if;  
 
            set total = total + c;  
 
            end loop;  
 
            close cur;  
 
        select _n,n,total;  
 
    end;  
 
    begin  
 
      
 
    end;  
 
    end loop;  
 
    close cur;  
 
END;  

call StatisticStore3();
 
上面就是实现一个嵌套循环,当然这个例子比较牵强。凑合看看就行。
 
动态SQL
 
Mysql 支持动态SQL的功能
 
set @sqlStr='select * from table where condition1 = ?';  
 
prepare s1 for @sqlStr;  
 
--如果有多个参数用逗号分隔  execute s1 using @condition1;  
 
--手工释放,或者是 connection 关闭时, server 自动回收  deallocate prepare s1;
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!