使用循环¶
Snowflake Scripting 支持以下类型的循环:
本主题说明如何使用这些类型的循环中的每一种。
FOR 循环¶
FOR 循环按照指定次数或者为结果集中的每一行重复执行一系列步骤。Snowflake Scripting 支持以下类型的 FOR 循环:
接下来的部分将介绍如何使用这些类型的 FOR 循环。
基于计数器的 FOR 循环¶
基于计数器的 FOR 循环执行指定的次数。
基于计数器的 FOR 循环的语法为:
FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP }
<statement>;
[ <statement>; ... ]
END { FOR | LOOP } [ <label> ] ;
例如,以下 FOR 循环执行 5 次:
DECLARE
counter INTEGER DEFAULT 0;
maximum_count INTEGER default 5;
BEGIN
FOR i IN 1 TO maximum_count DO
counter := counter + 1;
END FOR;
RETURN counter;
END;
注意:如果您在 Python Connector 代码中使用 SnowSQL、Classic Console 或者 execute_stream
或 execute_string
方法,请改用本示例(请参阅 在 SnowSQL、Classic Console 和 Python Connector 中使用 Snowflake Scripting):
EXECUTE IMMEDIATE $$
DECLARE
counter INTEGER DEFAULT 0;
maximum_count INTEGER default 5;
BEGIN
FOR i IN 1 TO maximum_count DO
counter := counter + 1;
END FOR;
RETURN counter;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
| 5 |
+-----------------+
有关 FOR 循环的完整语法和详细信息,请参阅 FOR (Snowflake Scripting)。
基于游标的 FOR 循环¶
:doc:` 基于游标 <cursors>` 的 FOR 循环会遍历结果集。迭代次数由 :doc:`游标 <cursors>`中的行数决定。
基于游标的 FOR 循环的语法为:
FOR <row_variable> IN <cursor_name> DO
<statement>;
[ <statement>; ... ]
END FOR [ <label> ] ;
本节中的示例使用了以下 invoices
表中的数据:
CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
(11.11),
(22.22);
以下示例使用 FOR 循环来遍历 invoices
表的游标中的行:
DECLARE
total_price FLOAT;
c1 CURSOR FOR SELECT price FROM invoices;
BEGIN
total_price := 0.0;
FOR record IN c1 DO
total_price := total_price + record.price;
END FOR;
RETURN total_price;
END;
注意:如果您在 Python Connector 代码中使用 SnowSQL、Classic Console 或者 execute_stream
或 execute_string
方法,请改用本示例(请参阅 在 SnowSQL、Classic Console 和 Python Connector 中使用 Snowflake Scripting):
EXECUTE IMMEDIATE $$
DECLARE
total_price FLOAT;
c1 CURSOR FOR SELECT price FROM invoices;
BEGIN
total_price := 0.0;
FOR record IN c1 DO
total_price := total_price + record.price;
END FOR;
RETURN total_price;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
| 33.33 |
+-----------------+
有关 FOR 循环的完整语法和详细信息,请参阅 FOR (Snowflake Scripting)。
基于 RESULTSET 的 FOR 循环¶
基于 RESULTSET 的 FOR 循环会遍历结果集。迭代次数由 RESULTSET 查询返回的行数决定。
基于 RESULTSET 的 FOR 循环的语法为:
FOR <row_variable> IN <RESULTSET_name> DO
<statement>;
[ <statement>; ... ]
END FOR [ <label> ] ;
本节中的示例使用了以下 invoices
表中的数据:
CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
(11.11),
(22.22);
以下代码块使用 FOR 循环遍历 invoices
表的 RESULTSET 中的行:
DECLARE
total_price FLOAT;
rs RESULTSET;
BEGIN
total_price := 0.0;
rs := (SELECT price FROM invoices);
FOR record IN rs DO
total_price := total_price + record.price;
END FOR;
RETURN total_price;
END;
注意:如果您在 Python Connector 代码中使用 SnowSQL、Classic Console 或者 execute_stream
或 execute_string
方法,请改用本示例(请参阅 在 SnowSQL、Classic Console 和 Python Connector 中使用 Snowflake Scripting):
EXECUTE IMMEDIATE $$
DECLARE
total_price FLOAT;
rs RESULTSET;
BEGIN
total_price := 0.0;
rs := (SELECT price FROM invoices);
FOR record IN rs DO
total_price := total_price + record.price;
END FOR;
RETURN total_price;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
| 33.33 |
+-----------------+
有关 FOR 循环的完整语法和详细信息,请参阅 FOR (Snowflake Scripting)。
WHILE 循环¶
当条件为 true 时,WHILE 循环进行迭代。在 WHILE 循环中,在即将执行循环主体之前检验条件。如果条件在第一次迭代之前为 false,则循环的主体一次都不会执行。
WHILE 循环的语法为:
WHILE ( <condition> ) { DO | LOOP }
<statement>;
[ <statement>; ... ]
END { WHILE | LOOP } [ <label> ] ;
例如:
BEGIN
LET counter := 0;
WHILE (counter < 5) DO
counter := counter + 1;
END WHILE;
RETURN counter;
END;
注意:如果您在 Python Connector 代码中使用 SnowSQL、Classic Console 或者 execute_stream
或 execute_string
方法,请改用本示例(请参阅 在 SnowSQL、Classic Console 和 Python Connector 中使用 Snowflake Scripting):
EXECUTE IMMEDIATE $$
BEGIN
LET counter := 0;
WHILE (counter < 5) DO
counter := counter + 1;
END WHILE;
RETURN counter;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
| 5 |
+-----------------+
有关 WHILE 循环的完整语法和详细信息,请参阅 WHILE (Snowflake Scripting)。
REPEAT 循环¶
REPEAT 循环一直进行迭代,:emph:` 直至 ` 条件为 true。在 REPEAT 循环中,在执行循环主体之后立即检验条件。因此,循环的主体始终至少执行一次。
REPEAT 循环的语法为:
REPEAT
<statement>;
[ <statement>; ... ]
UNTIL ( <condition> )
END REPEAT [ <label> ] ;
例如:
BEGIN
LET counter := 5;
LET number_of_iterations := 0;
REPEAT
counter := counter - 1;
number_of_iterations := number_of_iterations + 1;
UNTIL (counter = 0)
END REPEAT;
RETURN number_of_iterations;
END;
注意:如果您在 Python Connector 代码中使用 SnowSQL、Classic Console 或者 execute_stream
或 execute_string
方法,请改用本示例(请参阅 在 SnowSQL、Classic Console 和 Python Connector 中使用 Snowflake Scripting):
EXECUTE IMMEDIATE $$
BEGIN
LET counter := 5;
LET number_of_iterations := 0;
REPEAT
counter := counter - 1;
number_of_iterations := number_of_iterations + 1;
UNTIL (counter = 0)
END REPEAT;
RETURN number_of_iterations;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
| 5 |
+-----------------+
有关 REPEAT 循环的完整语法和详细信息,请参阅 REPEAT (Snowflake Scripting)。
LOOP 循环¶
LOOP 循环一直执行,直到执行 BREAK 命令为止。此类 BREAK 命令通常嵌入在分支逻辑中(例如 IF 语句 或 CASE 语句)。
LOOP 语句的语法为:
LOOP
<statement>;
[ <statement>; ... ]
END LOOP [ <label> ] ;
例如:
BEGIN
LET counter := 5;
LOOP
IF (counter = 0) THEN
BREAK;
END IF;
counter := counter - 1;
END LOOP;
RETURN counter;
END;
注意:如果您在 Python Connector 代码中使用 SnowSQL、Classic Console 或者 execute_stream
或 execute_string
方法,请改用本示例(请参阅 在 SnowSQL、Classic Console 和 Python Connector 中使用 Snowflake Scripting):
EXECUTE IMMEDIATE $$
BEGIN
LET counter := 5;
LOOP
IF (counter = 0) THEN
BREAK;
END IF;
counter := counter - 1;
END LOOP;
RETURN counter;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
| 0 |
+-----------------+
有关 LOOP 循环的完整语法和详细信息,请参阅 LOOP (Snowflake Scripting)。
终止循环或迭代¶
在循环构造中,可以指定循环或循环的迭代必须在何时提前终止。接下来的部分将对此进行更详细的解释:
终止循环¶
通过执行 BREAK 命令,可以明确地提前终止循环。BREAK(及其同义词 EXIT)会立即停止当前迭代,并跳过任何剩余的迭代。可以将 BREAK 视为在循环结束后跳转到第一个可执行语句。
BREAK 在 LOOP 循环中是必需的,但在 WHILE、FOR 和 REPEAT 循环中则并非必需。在大多数情况下,如果有要跳过的语句,可以使用标准分支结构( IF 语句 和 CASE 语句 )来控制要执行循环中的哪些语句。
BREAK 命令本身通常位于 IF 或 CASE 语句中。
在不终止循环的情况下终止迭代¶
可以使用 CONTINUE 或 ITERATE 命令跳转到循环迭代的末尾,以跳过循环中的其余语句。循环在下一次迭代开始时继续。
很少需要进行这种跳转。在大多数情况下,如果有要跳过的语句,可以使用标准分支结构( IF 语句 和 CASE 语句 )来控制要执行循环中的哪些语句。
CONTINUE 或 ITERATE 命令本身通常位于 IF 或 CASE 语句中。
指定终止后应继续执行的位置¶
在 BREAK 或 CONTINUE 命令中,如果需要在代码中的特定点(例如嵌套循环中的外循环)继续执行,请指定一个标签,用于标识应继续执行的点。
下面的示例在嵌套循环中演示了这一点:
BEGIN
LET inner_counter := 0;
LET outer_counter := 0;
LOOP
LOOP
IF (inner_counter < 5) THEN
inner_counter := inner_counter + 1;
CONTINUE OUTER;
ELSE
BREAK OUTER;
END IF;
END LOOP INNER;
outer_counter := outer_counter + 1;
BREAK;
END LOOP OUTER;
RETURN ARRAY_CONSTRUCT(outer_counter, inner_counter);
END;
注意:如果您在 Python Connector 代码中使用 SnowSQL、Classic Console 或者 execute_stream
或 execute_string
方法,请改用本示例(请参阅 在 SnowSQL、Classic Console 和 Python Connector 中使用 Snowflake Scripting):
EXECUTE IMMEDIATE $$
BEGIN
LET inner_counter := 0;
LET outer_counter := 0;
LOOP
LOOP
IF (inner_counter < 5) THEN
inner_counter := inner_counter + 1;
CONTINUE OUTER;
ELSE
BREAK OUTER;
END IF;
END LOOP INNER;
outer_counter := outer_counter + 1;
BREAK;
END LOOP OUTER;
RETURN ARRAY_CONSTRUCT(outer_counter, inner_counter);
END;
$$;
在此示例中:
有一个标记为 INNER 的循环,它嵌套在标记为 OUTER 的循环中。
CONTINUE OUTER 让带有 OUTER 标签的循环开始另一次迭代。
BREAK OUTER 终止内循环,并将控制权转移到外循环(标记为 OUTER)的末尾。
此命令的输出为:
+-----------------+
| anonymous block |
|-----------------|
| [ |
| 0, |
| 5 |
| ] |
+-----------------+
如输出所示:
inner_counter
最多递增到 5。CONTINUE OUTER 开始新的外循环迭代,新的外循环又会开始新的内循环迭代,内循环将计数器递增到 5。这些迭代一直持续到inner_counter
的值等于 5,BREAK OUTER 会终止内循环为止。outer_counter
从不递增。由于 BREAK OUTER 将控制权转移到外循环的末尾,因此从不会到达让此计数器递增的语句。