• MYSQL学习拓展一:MySQL 存储过程之游标的使用!


    一、MySQL游标的概念

      游标介绍:

          MySQL的游标(cursor)是一个重要的概念,通过查找资料与自己的理解,主要得出以下几点关于自己的理解。

            有数据缓冲的思想:游标的设计是一种数据缓冲区的思想,用来存放SQL语句执行的结果。 

            先有数据基础:游标是在先从数据表中检索出数据之后才能继续灵活操作的技术。

             类似于指针:游标类似于指向数据结构堆栈中的指针,用来pop出所指向的数据,并且只能每次取一个。

      游标优缺点:

        游标的优点:

          因为游标是针对行操作的,所以对从数据库中select查询得到的每一行可以进行分开的独立的相同或不同的操作,是一种分离的思想。可以满足对某个结果行进行特殊的操作。

         游标与基于游标位置的增删改查能力。 MySQL数据库中没有专门描述一行的表达形式,但这是需要的,所以,个人理解的话,我觉得游标是在关系数据库这种面向集合的系统中抽离出来,

        单独针对行进行表达(也可以理解成网上资料说的:游标是面向集合与面向行的设计思想之间的一种桥梁

        游标缺点:

          游标的缺点是针对有点而言的,也就是只能一行一行操作,在数据量大的情况下,是不适用的,速度过慢。这里有个比喻就是:当你去ATM存钱是希望一次性存完呢,

        还是100一张一张的存,这里的100一张一张存就是游标针对行的操作。 数据库大部分是面对集合的,业务会比较复杂,而游标使用会有死锁,影响其他的业务操作,不可取。 当数据量大时,使用游标会造成内存不足现象。

      游标的使用场景

          针对游标的优缺点,我总结游标的使用场景,主要用在循环处理、存储过程、函数中使用,用来查询结果集,就比如:我们需要从表中循环判断并得到想要的结果集,这时候使用游标操作很方便速度也很快。

    二、游标的使用

      游标的使用步骤

          游标的使用一般分为5个步骤,主要是:定义游标->打开游标->使用游标->关闭游标->释放游标。

          定义游标

            语法为:

    DECLARE <游标名> CURSOR FOR select语句;

          打开游标

            打开游标很简单就是下面的语句

    open <游标名>    

          使用游标

            使用游标需要用关键字fetch来取出数据,然后取出的数据需要有存放的地方,我们需要用declare声明变量存放列的数据其语法格式为:

    declare 变量1 数据类型(与列值的数据类型相同)
    declare 变量2 数据类型(与列值的数据类型相同)
    declare 变量3 数据类型(与列值的数据类型相同)
    FETCH [NEXT | PRIOR | FIRST | LAST] FROM <游标名> [ INTO 变量名1,变量名2,变量名3[,…] ]

             说明:

              NEXT:取下一行的数据,游标一开始默认的第一行之前,故要让游标指向第一行,就必须第一次就执行FETCH NEXT操作

              INTO:将一行中每个对应的列下的数据放到与列 的数据类型相同的变量中。

          关闭游标:

            很简单的使用语句:

    close <游标名>;

           释放游标:

    deallocate <变量名>;

       具体示例:

          未使用循环的游标实例:

     1 --默认数据
     2 DROP TABLE IF EXISTS `shops_info`;
     3 CREATE TABLE `shops_info` (
     4   `pid` int(11) NOT NULL,
     5   `name` varchar(20) NOT NULL,
     6   `price` int(11) NOT NULL,
     7   `pdesc` varchar(20) NOT NULL,
     8   PRIMARY KEY (`pid`)
     9 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    10 
    11 INSERT INTO `shops_info` VALUES 
    12 (1,'手机',2500,'打电话'),
    13 (2,'电话机',5000,'看电视'),
    14 (3,'电饭煲',400,'煮饭');
    默认数据测试

            具体操作:

     1 --查询shops_info第二行数据的全部信息
     2 drop procedure if exists cursor_test;
     3 delimiter //
     4 create procedure cursor_test()
     5 begin
     6     -- 声明与列的类型相同的四个变量
     7     declare id varchar(20); 
     8     declare pname varchar(20); 
     9     declare pprice varchar(20);
    10     declare pdescription varchar(20);
    11  
    12 -- 1、定义一个游标mycursor
    13     declare mycursor cursor for
    14   select *from shops_info WHERE pid=2;
    15 -- 2、打开游标
    16     open mycursor;
    17 -- 3、使用游标获取列的值
    18     fetch  mycursor into id,pname,pprice,pdescription; 
    19 -- 4、显示结果
    20     select id,pname,pprice,pdescription;
    21 -- 5、关闭游标
    22     close mycursor;
    23 end;
    24 //
    25 delimiter ;
    26 call cursor_test();
    无循环游标测试

           使用循环的游标实例:

     1 CREATE TABLE IF NOT EXISTS `store` (
     2   `id` int(11) NOT NULL AUTO_INCREMENT,
     3   `name` varchar(20) NOT NULL,
     4   `count` int(11) NOT NULL DEFAULT '1',
     5   PRIMARY KEY (`id`)
     6 ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7;
     7 
     8 INSERT INTO `store` (`id`, `name`, `count`) VALUES
     9 (1, 'android', 15),
    10 (2, 'iphone', 14),
    11 (3, 'iphone', 20),
    12 (4, 'android', 5),
    13 (5, 'android', 13),
    14 (6, 'iphone', 13);
    默认数据

            具体操作

     1 --统计这个表中'iphone'一共多少台
     2 delimiter //
     3 drop procedure if exists StatisticStore;
     4 CREATE PROCEDURE StatisticStore()
     5 BEGIN
     6     declare c int;
     7     declare n varchar(20);
     8     declare total int default 0;
     9 
    10     declare done int default false;
    11     declare cur cursor for select name,count from store where name = 'iphone';
    12     declare continue HANDLER for not found set done = true;
    13 
    14     open cur;
    15     read_loop:loop
    16     fetch cur into n,c;
    17     if done then
    18         leave read_loop;    
    19     end if;
    20     set total = total + c;
    21     end loop;
    22     close cur;
    23 
    24     select total;
    25 END;
    26 //
    27 
    28 delimiter ;
    29 call StatisticStore();
    有循环游标操作测试

            讲解:

    --统计这个表中'iphone'一共多少台
    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;
    //
    
    --修改回默认结束符
    delimiter ;
    --调用存储过程
    call StatisticStore();
    这都是我对自己学习过程的理解,如有错误请指出!我算一个小白了。
  • 相关阅读:
    各种web页面中的绘图技术对比
    32位和64位操作系统
    mysql新建用户本地无法登录
    ruby libmysqlclient.18.dylib
    jenkins创建git任务连接时遇到的问题
    mybatis 打印日志log4j.properties
    使用shell统计出出现次数排名top10的网址(在博客园中没找到,特转一下)
    ActiveMQ和Tomcat的整合应用(转)
    java 哪些情况下会使对象锁释放
    Web容器与Servlet
  • 原文地址:https://www.cnblogs.com/darwinli/p/9052796.html
Copyright © 2020-2023  润新知