使用游标
游标(cursor)
- 游标是结果集
- 是一条语句检索出来的结果集
- 是一个存储在Mysql服务器上的数据库查询
存储游标之后mysql可以根据需要浏览和滚动数据
只能用于存储过程(或者函数)
使用游标
使用游标的步骤
- 声明(定义)游标(此时没有检索数据,只是定义要使用的select语句)
- 打开游标以供使用(实际的检索过程)
- 根据需要检索出行
- 关闭游标(必须)
创建游标
delcare语句创建
DELIMITER $$CREATEPROCEDURE `sqllearn`.`processorders`()BEGINDECLARE ordernumbers CURSORFORSELECT order_num FROM `orders`;END$$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;

