【问题标题】:INSERT while LOOPing循环时插入
【发布时间】:2013-03-13 11:12:28
【问题描述】:

我想在循环时向表中插入一些记录。记录作为 varchar 选项卡传递给函数,即:

create function a(tab varchar[]) RETURNS void AS
$$
DECLARE 
  b varchar(20);
BEGIN
  FOREACH b IN ARRAY tab
   LOOP
      INSERT INTO....;
   END LOOP;
  RETURN;
END;
$$
LANGUAGE plpgsql;

但是,执行时出现错误:

ERROR:  syntax error at or near "FOREACH"
LINE 1: FOREACH  $1  IN ARRAY tab LOOP INSERT INTO x (c, ...
QUERY:  FOREACH  $1  IN ARRAY tab LOOP INSERT INTO x (c) VALUES ( $1)
CONTEXT:  SQL statement in PL/PgSQL function " near line ...

********** ERROR **********

ERROR: syntax error at or near "FOREACH"

有人知道为什么以及如何解决这个问题吗?

【问题讨论】:

  • Postgres 的哪个版本? FOREACH IN ARRAY 好像是在 9.1 中添加的。
  • 始终提供您正在使用的版本号。这是一个程序员的网站,您应该知道这样做。此外,如果您提供一个完整的示例,很有可能您根本不需要循环,这样会更快。

标签: postgresql loops plpgsql sql-insert


【解决方案1】:

FOREACH 结构是在 9.1 中添加的。对于早期版本,您可以通过以下方式使用unnest() 函数:

CREATE FUNCTION a(tab varchar[]) RETURNS void AS
$$
DECLARE 
  b varchar(20);
BEGIN
  FOR b IN SELECT unnest(tab)
  LOOP
    INSERT INTO x(c) VALUES (b);
  END LOOP;
  RETURN;
END;
$$ LANGUAGE plpgsql;

【讨论】:

    【解决方案2】:

    从 PostgreSQL 9.1 开始还有一个built-in way to loop through array slices:

    FOREACH x SLICE 1 IN ARRAY $1
    LOOP
       RAISE NOTICE 'row = %', x;
    END LOOP;
    

    其中x 必须是匹配的array 类型并且...

    SLICE值必须是不大于数组维数的整数常量

    对于一维数组,只需省略 SLICE 部分,x 可以是您在问题中显示的简单类型。

    【讨论】:

      【解决方案3】:

      我想添加一件事,那就是 unnest 取消了数组的所有级别:

      select * from unnest(ARRAY[ARRAY[1,2,3],Array[5,6,7]]);
       unnest 
      --------
            1
            2
            3
            5
            6
            7
      (6 rows)
      

      如果要循环遍历多维数组的一级,则应改为循环遍历以下内容

          FOR out_count IN
                          array_lower(in_transactions, 1) ..
                          array_upper(in_transactions, 1)
          LOOP
              -- Fill the bulk payments table
              INSERT INTO bulk_payments_in(id, amount)
              VALUES (in_transactions[out_count][1],
                      in_transactions[out_count][2]);
          END LOOP;
      

      【讨论】:

      • PostgreSQL 9.1+ 对此有专门的功能。
      猜你喜欢
      • 2012-11-24
      • 1970-01-01
      • 2012-07-10
      • 2020-07-10
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 2022-01-07
      • 1970-01-01
      相关资源
      最近更新 更多