码迷,mamicode.com
首页 > 数据库 > 详细

MySQL Crash Course #16# Chapter 24. Using Cursors + mysql 循环

时间:2018-04-23 16:34:40      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:没有   mysql   知识   boolean   学习笔记   SQ   exists   blog   etc   

 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 02000 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 02000 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 循环

标签:没有   mysql   知识   boolean   学习笔记   SQ   exists   blog   etc   

原文地址:https://www.cnblogs.com/xkxf/p/8916426.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!