游标
游标
MYSQL的SELECT返回所有与条件匹配的记录,组成结果集。
如果我们想获取结果集中的某一行或者某些行,可以使用LIMIT和OFFEST子句
这种方法不便于进行批处理。
如果我们想在检索出的行中前进一行或者多行,并提取数据,可以使用游标
定义:
游标是存储在MYSQL服务器上的数据库查询,他不是SELECT语句,而是被该语句检索出来的结果集
游标主要由于交互式应用程序,存储了游标之后,应用程序可以根据需要,滚动或者浏览其中的数据
使用游标的步骤
游标只能应用于存储过程和存储函数中。
- 声明游标
- 打开游标
- 获取数据
- 关闭游标(显示和隐式)
声明游标
MYSQL使用DECLARE声明游标
游标必须在存储过程和函数中声明
语法:
DELIMITER $$
CREATE PROCEDURE procedure_name()
BEGIN
DECLARE ordernumbers CURSOR FOR SELECT order_num FROM tables
END$$
DELIMITER ;
在存储过程完成后,游标就会关闭
打开和关闭游标
使用OPEN ordernumbers打开游标
使用CLOSE ordernumbers关闭游标
CLOSE可以释放游标使用的内存和资源
声明过的游标可以重复使用,用OPEN语句可以直接打开使用
隐式关闭:如果没有显式关闭,存储过程的END会自动关闭游标
使用游标数据
使用FECTH 语句从游标有检索数据
FETCH可以指定检索的列,以及检索出来的数据存储在什么位置(通常是局部变量)
FETCH作用:从已打开的游标结果集中读取下一行,并把该行各列依次赋给局部变量。
🔺MySQL 游标是单向、不可滚动的,因此不能返回上一行或跳转到指定行。
语法:
DELIMITER $$
CREATE PROCEDURE procedures()
BEGIN
--声明局部变量
DECLARE o INT;
--声明游标
DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders;
--打开游标
OPEN ordernumbers;
--获取订单号
FETCH order_num INTO o;
--关闭游标
CLOSE ordernumbers;
END $$
DELIMITER ;
FETCH提供的变量数量和声明游标时检索的列数量一致
游标查询返回多少列,FETCH INTO 就必须提供多少个变量。
--声明局部变量
DECLARE v_order_num INT;
DECLARE v_order_date DATE;
DECLARE v_customer_id INT;
--声明游标
DECLARE cur_orders CURSOR FOR
SELECT order_num, order_date, customer_id
FROM orders;
--检索数据
FETCH cur_orders
INTO v_order_num, v_order_date, v_customer_id;
循环检索数据
通常使用REPEAT...END REPEAT来循环检索游标中的数据
与WHILE...DO...END WHILE不同
REPEAT...END REPEAT的结束条件定义在循环体底部,使用UNTIL退出循环
REPEAT循环
WHILE ...END WHILE 在程序执行前检查结果,而
REPEAT...END REPEAT在执行操作后检查结果
语法格式:
[begin_label:] REPEAT
sql_statement|statement_block
[LEAVE begin_label;]
sql_statement|statement_block;
[ITERATE begin_label;]
sql_statement|statement_block;
UNTIL Boolean_expression
END REPEAT [begin_label];
其中:UNTIL 后面是退出条件;条件为 TRUE 时退出;
❓定义退出条件
当FETCH检索到最后一行以后,会抛出 NOT FOUND错误
可以先定义局部变量done,再抛出错误时,定义异常处理即可退出循环体
DELIMITER $$
CREATE PROCEDURE procedures()
BEGIN
--声明局部变量
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
-- 声明继续处理程序
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done =1;
--声明游标
DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders;
--打开游标
OPEN ordernumbers;
--进行循环体
REPEAT
--获取订单号
FETCH order_num INTO o;
--退出循环体条件
UNTIL done
END REPEAT;
--关闭游标
CLOSE ordernumbers;
END $$
DELIMITER ;
其中:
具体来说,在游标未找到时,对应SQLSTATE '02000'
DECLARE 的次序
用 DECLARE 语句定义的局部变量必须在定义任意游标或句柄之前定义,而句柄必须在游标之后定义。不遵守此顺序将产生错误消息。
执行游标的存储过程
使用CALL执行存储过程
CALL procedure_name();

浙公网安备 33010602011771号