mysql中游标的使用案例详解(学习笔记)这篇讲得相当直白好懂了。

索引:

  1. cursor 基础讲解
  2. mysql 循环
  3. 书上的整合代码

cursor 基础讲解

cursor 有点类似于 JDBC 中的 ResultSet ,允许我们在执行 SELECT 之后,一行一行地 FETCH 数据。

它只能被用在存储过程中!如果把存储过程比作函数,cursor 只能在这个函数体中(存储过程的内部)定义、打开、关闭,一旦存储过程执行完毕,它将不再存在(可以把 cursor 理解为一个局部变量)。

定义一个 cursor ,这个时候并没有执行 SELECT 语句:

CREATE PROCEDURE processorders()
BEGIN
DECLARE ordernumbers CURSOR
FOR
SELECT ordernum FROM orders;
END;

打开 cursor,SELECT 语句就是在这个时候被执行的,数据被缓存到 cursor 中,在这之后可以 FETCH 数据:

OPEN ordernumbers;

关闭 cursor ,释放 cursor 所占用的所有内存和资源, 当然,即便不手动关闭,在存储过程结束时(执行到 END) cursor 也会自动关闭:

CLOSE ordernumbers;

接下来就是 FETCH 数据了,每次 FETCH 一次都是下一行!可以结合上面几个知识点做个小实验,上面是实验用的表:

DROP PROCEDURE IF EXISTS hello;

DELIMITER //

CREATE PROCEDURE hello()
BEGIN
-- 声明局部变量,用于临时存储 FETCH 结果
DECLARE o INT; -- 声明游标
DECLARE ordernumbers CURSOR
FOR
SELECT order_num FROM orders; -- 打开游标(执行SELECT,缓存数据)
OPEN ordernumbers; -- 取出第一个订单号放到 o 里,并打印
FETCH ordernumbers INTO o;
SELECT o; -- 取出第二个订单号放到 o 里,并打印
FETCH ordernumbers INTO o;
SELECT o; -- 关闭游标(释放内存、资源)
CLOSE ordernumbers; -- 重新打开游标(重新执行SELECT,缓存数据)
OPEN ordernumbers; -- 取出第 ? 个订单号放到 o 里,并打印
FETCH ordernumbers INTO o;
SELECT o; -- 可以猜到,依然是第一个订单号 END // DELIMITER ; CALL hello();

mysql 循环

mySQL 本身的循环其实挺简单的,但是书上写的循环有点特殊。

基本循环示例:

while ↓

DROP PROCEDURE IF EXISTS hello;

DELIMITER //

CREATE PROCEDURE hello()
BEGIN
DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO
SET v1 = v1 - 1;
SELECT v1;
END WHILE;
END // DELIMITER ; CALL hello();

repeat ↓

DROP PROCEDURE IF EXISTS hello;

DELIMITER //

CREATE PROCEDURE hello()
BEGIN
DECLARE v1 INT DEFAULT 5; REPEAT
SET v1 = v1 - 1;
SELECT v1;
UNTIL v1 = 0 END REPEAT;
END // DELIMITER ; CALL hello();

loop ↓

DROP PROCEDURE IF EXISTS hello;

DELIMITER //

CREATE PROCEDURE hello()
BEGIN
DECLARE v1 INT DEFAULT 5; label1: LOOP SET v1 = v1 - 1;
SELECT v1;
IF v1 > 0 THEN
ITERATE label1; -- 继续循环 相当于continue
END IF;
LEAVE label1; -- 相当于 break END LOOP;
END // DELIMITER ; CALL hello();

PS. 为了确保可以直接 COPY 到命令行执行,上面的代码缩进有点问题。。。

书上的循环示例:

CREATE PROCEDURE processorders()
BEGIN -- Declare local variables
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT; -- Declare the cursor
DECLARE ordernumbers CURSOR
FOR
SELECT order_num FROM orders; -- Declare continue handler
DECLARE CONTINUE HANDLER FOR SQLSTATE '' SET done=1; -- Open the cursor
OPEN ordernumbers; -- Loop through all rows
REPEAT -- Get order number
FETCH ordernumbers INTO o; -- End of loop
UNTIL done END REPEAT; -- Close the cursor
CLOSE ordernumbers; END;

首先要看懂这句话

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

意思就是出现 SQLSTATE '02000' 这句话时就执行 SET done=1

而 SQLSTATE '02000' 等价于 not found ,它是在 FETCH 不到数据的时候出现的,因此拿不到数据的时候 done 变为真就结束循环了。。。

书上的整合代码

CREATE PROCEDURE processorders()
BEGIN -- Declare local variables
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE t DECIMAL(8,2); -- Declare the cursor
DECLARE ordernumbers CURSOR
FOR
SELECT order_num FROM orders;
-- Declare continue handler
DECLARE CONTINUE HANDLER FOR SQLSTATE '' SET done=1; -- Create a table to store the results
CREATE TABLE IF NOT EXISTS ordertotals
(order_num INT, total DECIMAL(8,2)); -- Open the cursor
OPEN ordernumbers; -- Loop through all rows
REPEAT -- Get order number
FETCH ordernumbers INTO o; -- Get the total for this order
CALL ordertotal(o, 1, t); -- Insert order and total into ordertotals
INSERT INTO ordertotals(order_num, total)
VALUES(o, t); -- End of loop
UNTIL done END REPEAT; -- Close the cursor
CLOSE ordernumbers; END;

这些活到底谁来做好呢 ? 是上层应用程序 还是 数据库 ? 。 。。 待更新。。

MySQL Crash Course #16# Chapter 24. Using Cursors + mysql 循环的更多相关文章

  1. MySQL Crash Course #15# Chapter 23. Working with Stored Procedures

    以前写过类似的东西,用来自动生成数据. 你可以将 Stored Procedure 理解为可以重复使用的批处理文件. Stored Procedure 非常有用,我们应该尽可能地去使用它. 那么,应用 ...

  2. MySQL Crash Course #06# Chapter 13. 14 GROUP BY. 子查询

    索引 理解 GROUP BY 过滤数据 vs. 过滤分组 GROUP BY 与 ORDER BY 之不成文的规定 子查询 vs. 联表查询 相关子查询和不相关子查询. 增量构造复杂查询 Always ...

  3. MySQL Crash Course #05# Chapter 9. 10. 11. 12 正则.函数. API

    索引 正则表达式:MySQL only supports a small subset of what is supported in most regular expression implemen ...

  4. MySQL Crash Course #02# Chapter 3. 4 通配符. 分页

    索引 查看表.文档操作 检索必须知道的两件事 数据演示由谁负责 通配符.非必要不用 检索不同的行 限制结果集.分页查找 运用数据库.表全名 命令后加分号对于很多 DBMS 都不是必要的,但是加了也没有 ...

  5. MySQL Crash Course #08# Chapter 16. Using Different Join Types

    记文档还是相当重要的! 索引 假名的三个用途 自交(Self Joins) 自然交(Natural Joins) Outer Joins Using Table Aliases Using alias ...

  6. MySQL Crash Course #13# Chapter 21. Creating and Manipulating Tables

    之前 manipulate 表里的数据,现在则是 manipulate 表本身. INDEX 创建多列构成的主键 自动增长的规定 查看上一次插入的自增 id 尽量用默认值替代 NULL 外键不可以跨引 ...

  7. MySQL Crash Course #11# Chapter 20. Updating and Deleting Data

    INDEX Updating Data The IGNORE Keyword Deleting Data Faster Deletes Guidelines for Updating and Dele ...

  8. MySQL Crash Course #10# Chapter 19. Inserting Data

    INDEX BAD EXAMPLE Improving Overall Performance Inserting Multiple Rows INSTEAD OF Inserting a Singl ...

  9. MySQL Crash Course #04# Chapter 7. 8 AND. OR. IN. NOT. LIKE

    索引 AND. OR 运算顺序 IN Operator VS. OR NOT 在 MySQL 中的表现 LIKE 之注意事项 运用通配符的技巧 Understanding Order of Evalu ...

随机推荐

  1. Python 基础知识(一)

    1.Python简介 1.1.Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时 ...

  2. WCF之通信工厂的简单使用

    WCF服务端已经创建好了以后,客户端可以直接通过选择服务引用,直接生成客户端的代理类,进而调用服务端的服务.其实说到底,服务端和客户端的通行就是通过终结点,然后在服务器端和客户端建立通信通道完成数据的 ...

  3. ubuntu16.04下安装pangolin

    安装教程,具体可以参考github上pangolin的安装文档 https://github.com/stevenlovegrove/Pangolin 首先要安装pangolin的各种依赖项 Glew ...

  4. PyQT5初学(一)

    PyQt5 是Digia的一套Qt5与python绑定的应用框架,同时支持2.x和3.x.本教程使用的是3.x.Qt库由Riverbank Computing开发,是最强大的GUI库之一 ,官方网站: ...

  5. The Unique MST POJ - 1679 最小生成树判重

    题意:求一个无向图的最小生成树,如果有多个最优解,输出"Not Unique!" 题解: 考虑kruskal碰到权值相同的边: 假设点3通过边(1,3)连入当前所维护的并查集s. ...

  6. MySQL在linux上(cmake)的source code安装方法

    1.安装前准备: 1)必备的包和工具  gcc/g++ :MySQL 5.6开始,需要使用g++进行编译.  cmake  :MySQL 5.5开始,使用cmake进行工程管理,cmake需要2.8以 ...

  7. Python实现简单HTTP服务器(一)

    一.返回固定内容 # coding:utf-8 import socket from multiprocessing import Process def handle_client(client_s ...

  8. LoadRunner-迭代和并发设置

    迭代:指运行一次脚本时某段代码块(action)循环执行的次数,串行执行 并发:指同时运行脚本的次数,并行执行(多个用户同时跑) 以下是用例和对应的相关设置 Iterations是在Vuser Gen ...

  9. Django的调试方法

    web程序调试起来和桌面程序有着很大的差别,对于Django程序来说调试更是个问题.我们可以用postman发送http请求,下面就介绍几种调试方法: 1.在Eclipse+Pydev中调试Djang ...

  10. 完成向后台添加用户的ssm项目,完整版

    1:ssm框架整合 1.1添加maven依赖pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: ...