FOREACH

使用 FOREACH 语句声明一个直接游标,该游标可以查询和操纵查询返回的结果集的多个的行或者来自集合的多个元素。

语法

SPL 的 FOREACH 语句可以创建的直接顺序游标与 SQL 的 DECLARE 语句可以在 SPL 例程中创建的动态游标不同。(有关 SPL 例程中动态游标的语法和用法,请参阅在 SPL 例程中声明动态游标。)

例程调用
元素 描述 限制 语法
cursor 作为直接游标的名称而声明的标识符 在例程的游标名称、准备好的语句以及 SPL 变量中必须是唯一的 标识符
data_var 接收返回值的调用例程中的 SPL 变量 data_var 的数据类型必须与返回的值相对应 标识符
function, procedure 要执行的 SPL 函数或过程 函数或过程必须存在 数据库对象名
SPL_var 包含要执行例程的名称的 SPL 变量 必须是 CHAR 、VARCHAR 、NCHAR 或 NVARCHAR 类型 标识符

用法

要执行 FOREACH 语句,数据库服务器应采用以下操作:
  1. 它声明并隐式地打开游标。
  2. 它从包含在 FOREACH 循环中的查询获取第一行,否则从调用的例程获取第一组值。
  3. 它对变量列表中的每个变量赋值,所赋的值是来自 SELECT 语句或调用的例程创建的活动集合的相应值。
  4. 它执行语句块。
  5. 它从 SELECT 语句获取下一行或对每个迭代调用例程,并且重复步骤 3 和 4。
  6. 当它发现没有其它行满足 SELECT 语句或调用的例程时,它会终止循环。当循环终止时,它关闭隐式游标。

因为语句块包含其它 FOREACH 语句,所以可以嵌套游标。对于嵌套的游标数量没有限制。

返回多个行、集合元素或值集合的 SPL 例程被称为游标函数。只返回一行或一个值的 SPL 例程是非游标函数

该 SPL 过程使用 SELECT ... INTO 子句、显式地已命名游标和过程调用来说明 FOREACH 语句:
CREATE PROCEDURE foreach_ex()
                          DEFINE i, j INT;
                          FOREACH SELECT c1 INTO i FROM tab ORDER BY 1
                          INSERT INTO tab2 VALUES (i);
                          END FOREACH
                          FOREACH cur1 FOR SELECT c2, c3 INTO i, j FROM tab
                          IF j > 100 THEN
                          DELETE FROM tab WHERE CURRENT OF cur1;
                          CONTINUE FOREACH;
                          END IF
                          UPDATE tab SET c2 = c2 + 10 WHERE CURRENT OF cur1;
                          END FOREACH
                          FOREACH EXECUTE PROCEDURE bar(10,20) INTO i
                          INSERT INTO tab2 VALUES (i);
                          END FOREACH
                          END PROCEDURE; -- foreach_ex
当出现以下任意情形时,会关闭选择游标:
  • 游标不再返回行。
  • 游标是一个没有 HOLD 指定选择游标,并且使用 COMMIT 或 ROLLBACK 语句完成某项事务。
  • 执行 EXIT 语句,它转移对 FOREACH 语句的控制。
  • 在 FOREACH 语句的主体之内发生未俘获的异常。(请参阅 ON EXCEPTION。)
  • 正执行此游标例程的调用例程中的游标(在 FOREACH 循环中)出于任何原因而关闭。
注:
FOREACH 语句不能定义 SCROLL 游标。每个 FOREACH 游标都是一个顺序游标,它只能获取来自活动集顺序中的下一行。FOREACH 定义的游标每次打开时只能读取活动集。
1 请参阅 使用 SELECT ... INTO 语句
2 请参阅 参数
3 请参阅 语句块