MySQL游标
一、游标的概念
? 游标是一个存储在MySQL服务器上的数据库查询,它不是一条select语句,而是被该语句检索出来的结果集。有了游标可以方便的对该结果集进行逐行处理。
二、游标的使用
1. 创建游标
-- declare语句定义了名为ordernumbers的游标。存储过程处理完成后,游标就会消失(因为它局限于存储过程)。 create procedure processorders() begin declare ordernumbers cursor for select order_num from orders; end;
【注】不像多数DBMS,MySQL游标只能用于存储过程(和函数)。
2. 打开和关闭游标
-- 打开游标。在处理open语句时执行上面的select查询语句,存储检索出的数据以供浏览和滚动。 open ordernumbers;
-- 游标处理完成后,利用close语句释放游标使用的所有内部内存和资源。 close ordernumbers;
【注】当一个游标关闭后,如果需要再次使用它,可以使用open语句再次打开它。
? 如果你不明确关闭游标,MySQL将会在到达end语句时自动关闭它。
下面是前面例子的修改版本:
create procedure processorders() begin declare ordernumbers cursor for select order_num from orders; open ordernumbers; close ordernumbers; end; -- 这个存储过程声明、打开和关闭一个游标。但对检索出的数据什么也没做。
3. 使用游标数据
第一个例子从游标中检索第一行:
create procedure processorders() begin declare o int; declare ordernumbers cursor for select order_num from orders; open ordernumbers; -- 利用fetch检索出第一行的order_num存储到一个名为o的局部变量中。 fetch ordernumbers into o; close ordernumbers; end;
第二个例子检索游标中的所有行,从第一行到最后一行:
create procedure processorders() begin declare done boolean default 0; declare o int; declare ordernumbers cursor for select order_num from orders; /* 这条语句定义了一个continue handler,它是在条件出现时被执行的代码。这里,它指出当 sqlstate ‘02000‘出现时,set done = 1。sqlstate ‘02000‘是一个未找到条件,当 repeate由于没有更多的行供循环而不能继续时,出现这个条件。 */ declare continue handler for sqlstate ‘02000‘ set done = 1; open ordernumbers; -- 当done为真(非零)时结束循环。 repeat fetch ordernumbers into o; until done end repeat; close ordernumbers; end;
第三个例子对从游标中取出的数据进行某种实际的处理
create 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; -- ordertotal为在上一章创建的一个用来计算带税合计的存储过程 call ordertotal(o, 1, t); insert into ordertotals(order_num, total) values(o, t); until done end repeat; close ordernumbers; end; -- 此存储过程不返回数据,但它能创建和填充另一个表。