游标

由于MySQL检索返回的是一组成为结果集的行,可能是零行也可能是多行,但是之前学到的并没有能一行一行处理的方式。而有时候需要需要在检索出来的行中前进、后退一行或多行,这个时候需要使用游标。

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

游标在MySQL中只能用于存储过程或者函数

使用游标的流程

  • 在能够使用游标前,必须声明它。为了定义要使用的SELECT语句。
  • 声明游标后需要打开游标。这个过程用SELECT语句把数据实际检索出来。
  • 对于填有数据的游标,根据需要检索出各行。
  • 结束游标需要关闭它

打开和关闭游标

打开:OPEN CURSOR
关闭: CLOSE CURSOR

CURSOR指的是先前定义的游标名

如一个完整的打开关闭过程:

CREATE PROCEDURE processorder()
BEGIN
    -- Declare the cursor
    DECLARE ordernumbers CURSOR
    FOR
    SELECT order_num FROM orders;

    -- Open the cursor
    OPEN ordernumbers;

    -- Close the cursor
    CLOSE ordernumbers;
END//
Query OK, 0 rows affecte

这个存储过程只是做了声明、打开和关闭游标,没有对检索出的数据做任何操作。

使用游标数据

在游标打开后,可以使用FETCH语句来访问每行数据。可以指定检索哪列数据,数据存储在什么地方。

mysql> CREATE PROCEDURE processtitle()
    -> BEGIN
    ->     -- Declare local variables
    ->     DECLARE o VARCHAR(100);
    ->
    ->     -- Declare the cursor
    ->     DECLARE titlenumbers CURSOR
    ->     FOR
    ->     SELECT title FROM articles;
    ->
    ->     -- Open the cursor;
    ->     OPEN titlenumbers;
    ->
    ->     -- Get title number
    ->     FETCH titlenumbers INTO o;
    ->     
    ->     CLOSE titlenumbers;                    
    -> END//

这部分存储过程中,先定义了一个局部变量o,数据类型为VARCHAR,之后将articles表中的title列中的当前行(此例为第一行)数据传入变量o中。

再看一个例子:

mysql> CREATE PROCEDURE processtitles()
    -> BEGIN
    ->     -- Declare local variables
    ->     Declare done BOOLEAN DEFAULT 0;
    ->     Declare o VARCHAR(100);
    ->
    ->     -- Declare the cursor
    ->     DECLARE titlenumbers CURSOR
    ->     FOR
    ->     SELECT title FROM articles;
    ->
    ->     -- Declare continue handle
    ->     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
    ->
    ->     -- Open the cursor
    ->     OPEN titlenumbers;
    ->
    ->     -- Loop through all rows
    ->     REPEAT
    ->
    ->         -- Get title number
    ->         FETCH titlenumbers INTO o;
    ->
    ->     -- End of loop
    ->     UNTIL done END REPEAT;
    ->
    ->     -- Close the cursor
    ->     CLOSE titlenumbers;
    ->
    -> END//

此存储过程中定义了名为titlenumbers的游标,随后进行了重复执行语句DECLARE CONTINUE HANDLER, 对该列每行数据进行读取后逐行传入变量o中。
其中变量done决定了循环的结束点,当done为1时循环结束。02000指的是没有更多行循环是出现这个条件。