PL/pgSQL For 循环

简介:在本教程中,您将了解 PL/pgSQL for 循环语句以在整数范围或查询结果集上进行迭代。

使用 PL/pgSQL for 循环遍历整数范围

下面说明了 for 循环遍历整数范围的loop 语句的语法:

[ <<label>> ]
for loop_counter in [ reverse ] from.. to [ by step ] loop
    statements
end loop [ label ];

在这个语法中:

  • 首先, for loop 创建一个 loop_counter 只能在循环内部访问的整数变量。默认情况下, for loop 添加 step 到 loop_counter 每次迭代之后。但是,当您使用的 reverse 选项, for loop 减去 step 从 loop_counter 。
  • 其次, from and to 是指定范围下限和上限的表达式。for 循环在进入循环之前评估这些表达式。
  • 第三, step 下面的 by 关键字指定的迭代步骤。它默认为 1。该表达式仅 for loop 计算 step 一次。

以下流程图说明了该 for loop 语句:

PL/pgSQL FOR 循环

以下示例使用 for loop 语句迭代从 1 到 5 的五个数字,并在每次迭代中显示每个数字:

do $$ begin
   for counter in 1..5 loop
    raise notice 'counter: %', counter;
   end loop;
end; $$

输出:

NOTICE:  Counter: 1
NOTICE:  Counter: 2
NOTICE:  Counter: 3
NOTICE:  Counter: 4
NOTICE:  Counter: 5

以下示例迭代 5 个从 5 到 1 的数字,并显示每次迭代中的每个数字:

do $$ begin
   for counter in reverse 5..1 loop
      raise notice 'counter: %', counter;
   end loop;
end; $$

输出:

NOTICE:  Counter: 5
NOTICE:  Counter: 4
NOTICE:  Counter: 3
NOTICE:  Counter: 2
NOTICE:  Counter: 1

以下示例使用该 for loop 语句对从 1 到 6 的六个数字进行迭代。每次迭代后将 2 添加到计数器:

do $$ begin 
  for counter in 1..6 by 2 loop
    raise notice 'counter: %', counter;
  end loop;
end; $$

输出:

NOTICE:  Counter 1
NOTICE:  Counter 3
NOTICE:  Counter 5

使用 PL/pgSQL for 循环迭代结果集

以下语句显示了如何使用 for 循环语句迭代查询的结果集:

[ <<label>> ]
for target in query loop
    statements
end loop [ label ];

以下语句使用 for 循环显示前 10 名最长电影的片名。

do
$$ declare
    f record;
begin
    for f in select title, length 
           from film 
           order by length desc, title
           limit 10 
    loop 
    raise notice '%(% mins)', f.title, f.length;
    end loop;
end;
$$
NOTICE:  Chicago North(185 mins)
NOTICE:  Control Anthem(185 mins)
NOTICE:  Darn Forrester(185 mins)
NOTICE:  Gangs Pride(185 mins)
NOTICE:  Home Pity(185 mins)
NOTICE:  Muscle Bright(185 mins)
NOTICE:  Pond Seattle(185 mins)
NOTICE:  Soldiers Evolution(185 mins)
NOTICE:  Sweet Brotherhood(185 mins)
NOTICE:  Worst Banger(185 mins)

使用 PL/pgSQL for 循环遍历动态查询的结果集

以下形式的 for 循环语句允许您执行动态查询并迭代其结果集:

[ <<label>> ]
for row in execute query_expression [ using query_param [, ... ] ] 
loop
    statements
end loop [ label ];

在这个语法中:

  • 该 query_expression 是一个SQL语句。
  • 该 using 子句用于向查询传递参数。

以下块显示了如何使用 for loop 语句循环执行动态查询。它有两个配置变量:

  • sort_type: 1 按标题对电影进行排序,2 按发行年份对电影进行排序。
  • rec_count : 是要从 film 表中查询的行数。我们将 using 在 for 循环的子句中使用它。

这个匿名块根据 sort_type 变量组成查询,并使用 for 循环遍历结果集的行。

do $$ declare
    -- sort by 1: title, 2: release year
    sort_type smallint := 1; 
    -- return the number of films
    rec_count int := 10;
    -- use to iterate over the film
    rec record;
    -- dynamic query
    query text;
begin

    query := 'select title, release_year from film ';

    if sort_type = 1 then
        query := query || 'order by title';
    elsif sort_type = 2 then
      query := query || 'order by release_year';
    else 
       raise 'invalid sort type %s', sort_type;
    end if;

    query := query || ' limit $1';

    for rec in execute query using rec_count
        loop
         raise notice '% - %', rec.release_year, rec.title;
    end loop;
end;
$$

输出:

NOTICE:  2006 - Academy Dinosaur
NOTICE:  2006 - Ace Goldfinger
NOTICE:  2006 - Adaptation Holes
NOTICE:  2006 - Affair Prejudice
NOTICE:  2006 - African Egg
NOTICE:  2006 - Agent Truman
NOTICE:  2006 - Airplane Sierra
NOTICE:  2006 - Airport Pollock
NOTICE:  2006 - Alabama Devil
NOTICE:  2006 - Aladdin Calendar

如果将 更改 sort_type 为 2,您将获得以下输出:

NOTICE:  2006 - Grosse Wonderful
NOTICE:  2006 - Airport Pollock
NOTICE:  2006 - Bright Encounters
NOTICE:  2006 - Academy Dinosaur
NOTICE:  2006 - Ace Goldfinger
NOTICE:  2006 - Adaptation Holes
NOTICE:  2006 - Affair Prejudice
NOTICE:  2006 - African Egg
NOTICE:  2006 - Agent Truman
NOTICE:  2006 - Chamber Italian

在本教程中,您学习了各种形式的 PL/pgSQL for 循环语句