Skip to content

17.6 游标

游标CURSOR有以下属性:

  • Asensitive: 服务器可能会也可能不会复制它的结果表
  • Read only: 不可更新
  • Nonscrollable: 只能在一个方向上遍历,不能跳行

游标的声明必须在处理器之前声明,变量和状况声明之后。

例子:

CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR(16);
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;

1. 声明游标

DECLARE cursor_name CURSOR FOR select_statement

声明一个游标并关联到SELECT语句检索要遍历的记录。

  • SELECT语句不能含有INTO子句
  • 游标的声明必须在处理器之前声明,变量和状况之后声明。
  • 不允许声明相同的游标名字

2. 打开游标

OPEN cursor_name

打开一个先前声明的游标。

3. 取出游标指向的内容

FETCH [[NEXT] FROM] cursor_name INTO var_name [, var_name] ...

为关联指定游标(必须是打开的)的SELECT语句取出下一条记录,然后步进游标。

如果记录存在,获取的字段会被存在var_name中。检索的字段数必须匹配输出变量的数量。

如果记录不存在,会发生一个No Data的状况(Error number: 1643; Symbol: ER_SIGNAL_NOT_FOUND; SQLSTATE: 02000)。你可以为这种状况设置一个处理器。

注意:其它的操作也会引发这一错误,导致处理器一并处理了这种状况。如果有必要区分的话,将各自的处理器放在各自的BEGIN...END块中。

4. 关闭游标

CLOSE cursor_name

关闭先前打开的游标。

如果没有关闭了没有打开的游标会发生错误。

若没有明确地关闭游标,会在它声明的BEGIN...END块的末尾关闭。