FOR (Snowflake Scripting)¶
FOR
循环将一系列步骤重复特定的次数。次数可能由用户指定,也可能由 光标 中的行数指定。这两种 FOR
循环的语法略有不同。
有关循环的更多信息,请参阅 使用循环。
备注
本 Snowflake Scripting 结构仅在 Snowflake Scripting 区块 内有效。
语法¶
要循环 光标 中的所有行,请使用:
FOR <row_variable> IN <cursor_name> DO statement; [ statement; ... ] END FOR [ <label> ] ;
要循环指定次数,请使用:
FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP } statement; [ statement; ... ] END { FOR | LOOP } [ <label> ] ;
其中:
row_variable
指定遵循 对象标识符 规则的变量名。
不要在 DECLARE 或 BEGIN ...END 部分。不应在本地块的作用域中定义该名称。
该名称在
FOR
循环内有效,但在FOR
循环外无效。
row_variable
保存光标中的一行。使用点表示法访问该行中的字段。例如:
my_row_variable.my_column_name
下面的示例中包含一个更完整的示例。
counter_variable
指定遵循 对象标识符 规则的变量名。
counter_variable
的名称仅在FOR
循环内有效。如果在循环外部声明了同名变量,则外部变量和循环变量是分开的。在循环中,对该名称的引用将解析为循环变量。允许
FOR
循环中的代码读取计数器变量的值,但不应更改它。例如,不要手动递增计数器变量以更改步长。start
这是
counter_variable
的初始值。起始值应该是 INTEGER 或计算结果为 INTEGER 的表达式。
end
在
counter_variable
随着循环而递增后,这是counter_variable
的最终值。结束值应为 INTEGER 或计算结果为 INTEGER 的表达式。
end
值应该大于或等于start
值。如果end
小于start
,则循环执行 0 次(即使使用了REVERSE
关键字)。
cursor_name
要循环访问的光标的名称。
label
可选标签。此类标签可以是 BREAK (Snowflake Scripting) 或 CONTINUE (Snowflake Scripting) 语句的跳转目标。标签必须遵循 对象标识符 的命名规则。
使用说明¶
循环迭代到
end
点(包括该点)。例如,
FOR i IN 1 TO 10
循环 10 次,在最后一次迭代中,i
的值为 10。如果使用
REVERSE
关键字,则循环向下向后迭代到start
值(包括起始值)。一个循环可以包含多个语句。您可以使用(但不是必须使用):doc:
begin
:doc:` 块 </developer-guide/snowflake-scripting/blocks>` 来包含这些语句。可选关键字
REVERSE
使 Snowflake 从end
值开始,递减到start
值。尽管您可以在循环内部更改
counter_variable
的值,但 Snowflake 建议避免这样做。更改值会使代码更难理解。如果使用关键字
DO
,则在FOR
循环的末尾使用END FOR
。如果使用关键字LOOP
,则在END LOOP
循环的末尾使用FOR
。
示例¶
- 基于游标的 FOR 循环:
此示例演示如何使用 光标 对查询返回的所有行的 price
列中的值进行求和。此存储过程的行为有点像聚合函数。
CREATE or replace TABLE invoices (price NUMBER(12, 2)); INSERT INTO invoices (price) VALUES (11.11), (22.22);CREATE OR REPLACE PROCEDURE for_loop_over_cursor() RETURNS FLOAT LANGUAGE SQL AS $$ DECLARE total_price FLOAT; c1 CURSOR FOR SELECT price FROM invoices; BEGIN total_price := 0.0; OPEN c1; FOR rec IN c1 DO total_price := total_price + rec.price; END FOR; CLOSE c1; RETURN total_price; END; $$ ;下面是存储过程的输出:
CALL for_loop_over_cursor(); +----------------------+ | FOR_LOOP_OVER_CURSOR | |----------------------| | 33.33 | +----------------------+
- 基于计数器的 FOR 循环:
此示例演示如何使用 FOR
循环迭代指定的次数:
CREATE PROCEDURE simple_for(iteration_limit INTEGER) RETURNS INTEGER LANGUAGE SQL AS $$ DECLARE counter INTEGER DEFAULT 0; BEGIN FOR i IN 1 TO iteration_limit DO counter := counter + 1; END FOR; RETURN counter; END; $$;下面是存储过程的输出:
CALL simple_for(3); +------------+ | SIMPLE_FOR | |------------| | 3 | +------------+
以下示例演示如何使用 REVERSE
关键字倒计数。
CREATE PROCEDURE reverse_loop(iteration_limit INTEGER) RETURNS VARCHAR LANGUAGE SQL AS $$ DECLARE values_of_i VARCHAR DEFAULT ''; BEGIN FOR i IN REVERSE 1 TO iteration_limit DO values_of_i := values_of_i || ' ' || i::varchar; END FOR; RETURN values_of_i; END; $$;下面是存储过程的输出:
CALL reverse_loop(3); +--------------+ | REVERSE_LOOP | |--------------| | 3 2 1 | +--------------+
以下示例演示循环计数器变量与已声明的变量同名 (i
) 时的行为。在 FOR
循环中,对 i
的引用解析为循环计数器变量(而不是在循环外声明的变量)。
CREATE PROCEDURE p(iteration_limit INTEGER) RETURNS VARCHAR LANGUAGE SQL AS $$ DECLARE counter INTEGER DEFAULT 0; i INTEGER DEFAULT -999; return_value VARCHAR DEFAULT ''; BEGIN FOR i IN 1 TO iteration_limit DO counter := counter + 1; END FOR; return_value := 'counter: ' || counter::varchar || '\n'; return_value := return_value || 'i: ' || i::VARCHAR; RETURN return_value; END; $$;下面是存储过程的输出:
CALL p(3); +------------+ | P | |------------| | counter: 3 | | i: -999 | +------------+