跳到主要内容

游标执行流程

游标执行的完整流程包括声明游标(DECLARE)、打开游标(OPEN)、获取下一行(FETCH)和关闭游标(CLOSE)。

声明游标(DECLARE)

声明一个游标的语法如下:

DECLARE cursor_name CURSOR FOR select_statement

此语法将游标与一个 SELECT 语句相关联(SELECT 语句中不能包含 INTO 子句),SELECT 语句可以检索游标要遍历的行。如果要稍后提取行,请使用 FETCH 语句,此时要求 SELECT 语句检索到的列数必须与 FETCH 语句中指定的输出变量的数量相匹配。

游标声明必须出现在处理程序声明之前,变量和条件声明之后。一个存储程序可以包含多个游标声明,但在指定块中声明的游标必须具有唯一的名称。

在大多数情况下,通过使用带有 INFORMATION_SCHEMA 表的游标可以获得与 SHOW 语句等效的信息。

打开游标(OPEN)

打开已声明的游标语法如下:

OPEN cursor_name

获取下一行(FETCH)

获取与指定游标(必须打开)关联的 SELECT 语句的下一行,并前进游标指针的语法如下:

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

如果存在行,则获取的列存储在所命名的变量 var_name 中。SELECT 语句检索到的列数必须与 FETCH 语句中指定的输出变量的数量相匹配。

如果没有更多行可用时会出现无数据情况,即则 SQLSTATE 值为"02000"。要检测此情况,可以为其设置异常处理程序(或为其设置 NOT FOUND 条件)。需要注意的是,SELECT 或其他 FETCH 语句也可能会引发相同的情况,从而引发处理程序的执行。如果有必要区分是哪个操作引起了这种情况,请将该操作置于其自身的 BEGIN END 块中,以便只与自己的处理程序相关联。

关闭游标(CLOSE)

关闭之前打开的游标的语法如下:

CLOSE cursor_name

如果游标未打开时执行此语句,则会发生错误。如果没有显式关闭,游标将在其被声明的 BEGIN END 块执行结束时关闭。

示例

DELIMITER //

CREATE PROCEDURE hr_curdemo()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE x, y, z INT;
DECLARE cur1 CURSOR FOR SELECT id,salary FROM hr.emp;
DECLARE cur2 CURSOR FOR SELECT avg_sal FROM hr.avg;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cur1;
OPEN cur2;

read_loop: LOOP
FETCH cur1 INTO x, y;
FETCH cur2 INTO z;
IF done THEN
LEAVE read_loop;
END IF;
IF y < z THEN
INSERT INTO hr.low_sal VALUES (x,y);
ELSE
INSERT INTO hr.high_sal VALUES (x,z);
END IF;
END LOOP;

CLOSE cur1;
CLOSE cur2;
END //

Query OK, 0 rows affected