zoukankan      html  css  js  c++  java
  • 游标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;
  • 相关阅读:
    Effective C# 原则12:选择变量初始化而不是赋值语句
    Effective C# 原则20:明辨接口实现和虚函数重载的区别(译)
    Effective C# 原则18:实现标准的处理(Dispose)模式(译)
    Effective C# 原则19:选择定义和实现接口而不是继承(译)
    Is JoyFM goes over? Nope, I believe that JoyFM will stick together with us for a long time.
    Effective C# 原则15:使用using和try/finally来做资源清理(译)
    Effective C# 第二章:.Net资源管理(翻译)
    Effective C# 原则10: 明白GetHashCode()的缺陷(译)
    Effective C# 原则8:确保0对于值类型数据是有效的(翻译)
    Effective C# 原则23:避免返回内部类对象的引用(翻译)
  • 原文地址:https://www.cnblogs.com/hereisdavid/p/13547074.html
Copyright © 2011-2022 走看看