游标cursor

游标cursor

MySQL检索操作返回一组称为结果集的行。这组返回的行都是与SQL语句相匹配的零或多

行。简单的SELECT语句没办法得到第一行、下一行或前10行,也不存在每次一行的处理

所有行的简单方法,即批量处理行。

故要检索出来的行中前进或后退一或多行时,可以用游标。

游标是一个存储在MySQL服务器上的数据库查询,不是一条SELECT语句,而是被该语句

检索出来的结果集。在存储了游标后,应用程序可以根据需要滚动或浏览其中的数据。

主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改

只能用于存储过程,MySQL游标只能用于存储过程和函数

使用游标

  • 使用前,先声明游标,这一过程实际上没有检索数据,只是定义要使用的SELECT语句
  • 一旦声明后,必须打开游标以供使用,这个过程用前面定义的SELECT语句把数据实际检
  • 索出来
  • 对于填有数据的游标,根据需要检索各行
  • 结束游标使用时,要关闭游标

创建游标

DECLARE命名创建游标,并定义相应的SELECT语句,根据需要,带WHERE和其他语句

例一,定义ordernumbers游标,检索所有订单的SELECT语句

1 CREATE PROCEDURE processorders()
2 BEGIN
3     DECLARE ordernumbers CURSOR
4     FOR
5     SELECT order_num FROM orders;
6 END;    

DECLARE语句用来定义命名游标ordernumbers

存储过程处理完后,游标消失,因为游标仅局限于存储过程

打开和关闭游标

1 OPEN ordernumbers;

在处理OPEN语句时执行查询,存储检索出的数据以供浏览和滚动。

1 CLOSE ordernumbers;

CLOSE释放游标使用道德所有内部内存和资源,因此在每个游标不再需要时都应该关闭。

游标关闭后,若没有重新打开,则不能再使用,但使用声明过的游标不需要再次声明,用

OPEN语句打开即可。

如果不明确关闭游标,MySQL将在到达END语句时自动关闭。 

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare the cursor
 4     DECLARE ordernumbers CURSOR
 5     FOR
 6     SELECT order_num FROM orders;
 7     
 8     -- OPEN the cursor
 9     OPEN ordernumbers;
10     
11     -- CLOSE the cursor
12     CLOSE ordernumbers;
13 END;  

使用游标

游标被打开后,使用FETCH语句分别访问它的每一行。FETCH指定检索什么数据,检索

出来的数据存储在什么地方。游标还向前移动游标中的内部行指针,使下一条FETCH语句

检索下一行(不重复读取同一行)

 

例二、从游标中检索单个行:

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare local varitables
 4     DECLARE o INT;
 5     
 6     -- Declare the cursor
 7     DECLARE ordernumbers CURSOR
 8     FOR
 9     SELECT order_num FROM orders;
10     
11     -- Open the cursor
12     OPEN ordernumbers;
13     
14     -- Get order number
15     FETCH ordernumbers INTO o;
16     
17     -- Close the cursor
18     CLOSE ordernumbers;
19 END;

其中FETCH用来检索当前行的order_num列,自动从第一行开始,到一个名为o的局部声明的变量中,检索出的数据不做处理。

例三、循环检索数据,从第一行到最后一行:

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare local varitables
 4     DECLAE done BOOLEAN DEFAULT 0;
 5     DECLARE o INT;
 6     
 7     -- Declare the cursor
 8     DECLARE ordernumbers CURSOR
 9     FOR
10     SELECT order_num FROM orders;
11     
12     -- Declare continue handler
13     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
14     
15     -- Open the cursor
16     OPEN ordernumbers;
17     
18     --loop through all rows
19     REPEAT
20     
21         -- Get order number
22         FETCH ordernumbers INTO o;
23         
24     -- End of loop
25     UNTIL done END REPEAT;        
26     
27     -- Close the cursor
28     CLOSE ordernumbers;
29 END; 

使用FETCH检索当前order_num到声明的名为o的变量中,但与例一不同在于,FETCH是在REPEAT内,因此它反复执行知道done为真(DECLAE done BOOLEAN DEFAULT 0;)(UNTIL done END REPEAT;)

当(DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;)时done为真
这里定义了一个CONTINUE HANDLER,即条件出现时被执行的代码,当SQLSTATE '02000'出现时,done为1
SQLSTATE '02000'是一个未找到条件,当REPEAT循环完没法继续时,出现这个条件
如果调用这个存储过程,他将定义几个变量和一个CONTINUE HANDLER,定义并打开一个游标,重复读取所有行,然后关闭游标。

例四、对取出的数据进行

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare local varitables
 4     DECLARE done BOOLEAN DEFAULT 0;
 5     DECLARE o INT;
 6     DECLARE t DECIMAL(8,2);
 7     
 8     -- Declare the cursor
 9     DECLARE ordernumbers CURSOR
10     FOR
11     SELECT order_num FROM orders;
12     -- Declare continue handler
13     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
14     
15     -- Create a table to store the results
16     CREATE TABLE IF NOT EXISTS ordertotals
17         (order_num INT, total DECIMAL(8,2));
18     
19     -- Open the cursor
20     OPEN ordernumbers;
21     
22     --loop through all rows
23     REPEAT
24     
25         -- Get order number
26         FETCH ordernumbers INTO o;
27         
28         --Get the total for this order
29         CALL ordertotal(o,1,t);
30         
31         -- Insert order and total into ordertotals
32         INSERT INTO ordertotals(order_num,total)
33         VALUES(o,t);
34         
35     -- End of loop
36     UNTIL done END REPEAT;        
37     
38     -- Close the cursor
39     CLOSE ordernumbers;
40 END; 

增加变量t存储每个订单的合计。此存储过程还在运行中创建了一个新表(CREATE TABLE IF NOT EXISTS ordertotals),这个表将保存存储过程生成的结果。
FETCH取每个order_num,然后用CALL执行另一个存储过程来计算每个订单的带税的合计,结果存储到t。
最后用INSERT保存每个订单的订单号和合计。
可以用SELECT语句查看此存储过程创建的表

1 SELECT* FROM ordertotals;

 

posted @ 2020-08-22 21:04  HEREISDAVID  阅读(756)  评论(0编辑  收藏  举报