使用游标

游标(cursor)

  • 游标是结果集
  • 是一条语句检索出来的结果集
  • 是一个存储在Mysql服务器上的数据库查询

存储游标之后mysql可以根据需要浏览和滚动数据

只能用于存储过程(或者函数)

使用游标

使用游标的步骤

  1. 声明(定义)游标(此时没有检索数据,只是定义要使用的select语句)
  2. 打开游标以供使用(实际的检索过程)
  3. 根据需要检索出行
  4. 关闭游标(必须)

创建游标

delcare语句创建

  1. DELIMITER $$
  2. CREATE
  3. PROCEDURE `sqllearn`.`processorders`()
  4. BEGIN
  5. DECLARE ordernumbers CURSOR
  6. FOR
  7. SELECT order_num FROM `orders`;
  8. END$$
  9. DELIMITER ;

注意游标和存储过程一起使用

存储过程处理完,游标就会消失(因为它局限于存储过程)

打开和关闭游标

DELIMITER $$

USE `sqllearn`$$

DROP PROCEDURE IF EXISTS `processorders`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `processorders`()
BEGIN
DECLARE ordernumbers CURSOR
FOR 
SELECT order_num FROM `orders`;

OPEN ordernumbers;
CLOSE ordernumbers;
    END$$

DELIMITER ;

隐含关闭:不明确关闭,到end会自动关闭

使用游标数据

FETCH语句

  • 指定检索出来的数据
  • 检索出的数据存储的地方

检索单个行(第一行)

DELIMITER $$
USE `sqllearn`$$
DROP PROCEDURE IF EXISTS `processorders`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `processorders`()
BEGIN
DECLARE ordernumbers CURSOR
FOR 
SELECT order_num FROM `orders`;
OPEN ordernumbers;
FETCH ordernumbers INTO o;
CLOSE ordernumbers;
    END$$
DELIMITER ;

循环检索数据

DELIMITER $$

USE `sqllearn`$$

DROP PROCEDURE IF EXISTS `processorders`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `processorders`()
BEGIN
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE ordernumbers CURSOR
FOR 
SELECT order_num FROM `orders`;

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


OPEN ordernumbers;

REPEAT
    FETCH ordernumbers INTO o;
UNTIL done END REPEAT;
CLOSE ordernumbers;
    END$$

DELIMITER ;

用repeat和UNTIL 循环

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

continue handler定义条件出现时的代码

delcare 语句的次序

  • 局部变量
  • 游标
  • 句柄

存储过程、游标、逐行处理以及存储过程调用其他存储过程的一个完整的工作样例

DELIMITER $$

USE `sqllearn`$$

DROP PROCEDURE IF EXISTS `processorders`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `processorders`()
BEGIN
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE t DECIMAL(8,2);

DECLARE ordernumbers CURSOR
FOR 
SELECT order_num FROM `orders`;

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'SET done =1;
CREATE TABLE IF NOT EXISTS ordertotals(
order_num INT,
total DECIMAL(8,2)
);

OPEN ordernumbers;

REPEAT
    FETCH ordernumbers INTO o;
    CALL ordertotal(0,1,t);
    INSERT INTO ordertotals(order_num,total) VALUES(o,t);

UNTIL done END REPEAT;
CLOSE ordernumbers;
    END$$

DELIMITER ;
CALL processorders();
SELECT * FROM ordertotals;

游标 - 图1