设为首页 加入收藏

TOP

Mysql 游标初识(一)
2019-10-09 20:02:20 】 浏览:104
Tags:Mysql 游标 初识

MySql 游标初识

认识

游标(cursor), 按字面意思可理解为, 游动的标识, 或者叫做"光标", 这样更容易理解. 就好比现有一张表存储了n行记录, 然后我想每次取出一行, 进行为所欲为, 这时候就用到了游标cursor, 数据的搬运工, 搬运完当前数据(游标指向当前), 然后又移动到下一条数据的位置.

"移动", 和 "指向" 这两个词很重要, 跟C的指针有点类似, 举一个链表的例子吧. a -> b -> c -> d, 需求是求计算链表的长度. 则我们需要定义一个游标变量cursor, 默认定位到"a" 节点位置, 还需定义一个技术变量count 默认为0, 然后移动游标cursor (Python里 "=" 即表示"指向"), 沿着 a->b->c->d, 每移动一次, 则游标指向当前节点, 计数器加1....

应用场景, 在于, 好比一条 select xxx where xxx ; 返回的是一个查询集, 但我不想啪啪啪一顿返回一堆数据, 我要自己逐行检查和写逻辑判断, 这时候就需要cursor. 即, 一条sql, 对应N条数据, 取出(依次 or 自定义顺序) 数据的接口(interface) / 句柄, 就是游标, 沿着游标方向, 依次可以一次取出1行.

接口(interface)

接口泛指实体把自己提供给外界的一种抽象化物(可以为另一实体),用以由内部操作分离出外部沟通方法,使其能被内部修改而不影响外界其他实体与其交互的方式。

通俗理解, 就是, A只想用B的一些功能,但并不关心B是怎么实现的, 由此B根据A的需求, 提供一些能满足A的服务, 这些服务, 就是"接口".举几个栗子.

  • 我想开车, 车里面是什么样的我并不关系, 这时候车给了提供了, 方向盘, 油门,离合器, 刹车, 挡位等, 我就是能开了, 这些就是"接口" (好像不太恰当哦); 或者是想学外语, 这时候给我提给了一张VIP卡, 那我就可以学外语了, 这张VIP卡, 就是接口.
  • 我编写了一个web网站, 想让用户用微信, QQ, 微博, 支付宝账号也能登陆, 那这时候,我就要向这些大佬公司申请这些用户ID验证, 怎么验证我不管, 只按照他们提供的 "验证规则"传参进去, 等待就好, 那, 这个验证规则逻辑, 就是微信, 微博...向外界提供的接口.
  • 我想要操作电脑, 这时候, windows / linux 给我提给了 图形化 / 命令行 的方式让我操作, 这也是接口.
  • 创建一张MySql二维表存储数据, 我可以对其进行增删改查, 那这些功能, 也是接口.
  • 编码时, 调用自定义的或别人的或系统的类的方法时, 这些方法也是接口.

语法

  • 声明游标: declare 游标名 cursor for select _staetment;
  • 打开游标: open 游标名
  • 取出数据: fetch 游标名 into var1, var2 ....
  • 关闭游标: close 游标名
-- 文档说明
-- 游标声明必须在procedure 数据处理之前, 和在变量声明之后.
DECLARE cursor_name CURSOR FOR select_statement;
OPEN cursor_name;  -- 打开游标(当前块,唯一命名)
FETCH cursor_name INTO var_name, [, var_name] ... -- 读取游标数据, 并前进指针
CLOSE cursor_name;  -- 如果不close, 则会在其被声明的复合语句末尾被关闭

案例

用之前的goods, 表操作一波.

-- 查看一下数据
-- out
mysql> select * from goods;
+-----+------+-----+
| gid | name | num |
+-----+------+-----+
|   1 | cat  |  37 |
|   2 | dog  |  72 |
|   3 | pig  |  18 |
+-----+------+-----+
3 rows in set (0.09 sec)

-- 更新一波 cat 的数量吧
mysql> update goods set num = 100 where gid=1;

Query OK, 1 row affected (0.08 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from goods;
+-----+------+-----+
| gid | name | num |
+-----+------+-----+
|   1 | cat  | 100 |
|   2 | dog  |  72 |
|   3 | pig  |  18 |
+-----+------+-----+
3 rows in set (0.11 sec)

需求是要逐条取出每行数据, 而不是一下子都给我.

-- cursor: 依次获取每行数据
drop procedure if exists cur1;
delimiter //
create procedure cur1()
begin
    -- select * from goods; 每行有3个值, gid, name, num 
    -- 首先要定义变量来存储
    -- 声明和打开游标
    -- fetch 每行数据
    -- 处理逻辑
    -- 关闭游标
end //
delimiter ;

具体实现

drop procedure if exists cur1;
delimiter //
create procedure cur1()
begin
    -- select * from goods; 每行有3个值, gid, name, num 
    -- 首先就为每行数据, 定义相应临时变量来存储
    declare tmp_gid int;
    declare tmp_name varchar(20);
    declare tmp_num int;
    -- 声明和打开游标
    declare getGoods cursor for select gid, name, num from goods;
    open getGoods;
    -- fetch 每行数据, 要一一有对应的变量来接收哦
    fetch getGoods into tmp_gid, tmp_name, tmp_num;
    -- 处理逻辑(这里只打印一下)
    select tmp_gid, tmp_name, tmp_num;
    -- 关闭游标
    close getGoods;
    
end //
delimiter ;

-- out
mysql> call cur1();
+---------+----------+---------+
| tmp_gid | tmp_name | tmp_num |
+---------+----------+---------+
|       1 | cat      |     100 |
+---------+----------+---------+
1 row in set (0.14 sec)

与之前直接取出一行的区别在于, 控制权在我们手里, 真的可以为所欲为, 进一步可以进行判断,取值等各种编程操作, 真的可以为所欲为.

如何fetch多行呢?

-- fetch 多行 及 游标到尾(没有数据了, 不会报错)
drop procedure if exists cur1;
delimiter //
create procedure cur1()
begin
    declare tmp_gid int;
    declare tmp_name varchar(20);
    declare tmp_num i
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Redis 的主从同步(复制) 下一篇【JDBC】工具类的抽取

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目