【问题标题】:Postgres 9.6 How to loop over array and insert each array value into tables?Postgres 9.6 如何遍历数组并将每个数组值插入表中?
【发布时间】:2020-09-17 19:11:07
【问题描述】:

我似乎无法弄清楚这一点,以下是尝试使用 pgadmin 查询工具在 postgres 中作为 foreach 循环运行的项目数组,对于数组中的每个项目 x,执行 2 个插入语句其中x 是每个数组值:

我根据https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-FOREACH-ARRAY 第 42.6.7 节进行了尝试。遍历数组,这里有一些伪代码:

DO
$do$
BEGIN
   FOREACH x IN ['Apple','Banana','Cantaloupe']
   LOOP

    INSERT INTO foods.fruits(id, comment, fruit_name)
    VALUES ((SELECT MAX(id) + 1 FROM foods.fruits), 'a comment', x);

    INSERT INTO foods.fruits_ordered(id, price, fruit_id)
    VALUES ((SELECT MAX(id) + 1 FROM foods.fruits_ordered), '5.00', (SELECT id FROM foods.fruits WHERE fruit_name = x));

   END LOOP;
END
$do$;

这应该运行循环 3 次,总共进行 6 次插入。 知道如何让它工作吗?

【问题讨论】:

  • select max() + 1 是一种生成唯一 ID 的糟糕方法。您应该使用serial 列(基于序列)。但是您不需要 PL/pgSQL 或循环开头:dbfiddle.uk/…
  • 你得到什么错误?
  • 抱歉错过了第一个插入中的评论字段,第二个插入中的价格字段刚刚更新了它们,我得到的错误是 ERROR: syntax error at or near "[" btw

标签: postgresql for-loop plpgsql


【解决方案1】:

这个['Apple','Banana','Cantaloupe'] 可能不是一个正确的数组定义,这应该更像array['Apple','Banana','Cantaloupe']::varchar[]

固定的loop 可能类似于以下内容

...
FOREACH x IN array(select array['Apple','Banana','Cantaloupe']::varchar[])
...

接下来,x 应该在块开始之前声明(begin),如下

DO
$do$
/*
type could be text
Better be based on target field should be inserted as
foods.fruits.fruit_name%type
*/
declare x varchar(31); 
declare res text;
BEGIN
...

最终脚本可能类似于

DO
$do$
declare x _names.n%type;
BEGIN
   FOREACH x IN array(select array['Apple','Banana','Cantaloupe']::varchar[])
   LOOP
   /*inserts here...*/    
   END LOOP;
END
$do$;

另一种选择是使用unnest 函数,它将数组转换为行。

例如

select array[9,1,1,9,9,2]::int[]
/*
{9,1,1,9,9,2}
*/
select unnest("array") from (select array[9,1,1,9,9,2]::int[] as "array") as "req"
/*
9
1
1
9
9
2
*/

使用for x in select ...循环选择

【讨论】:

  • array(select array['Apple','Banana','Cantaloupe']::varchar[])可以简化为array['Apple','Banana','Cantaloupe']
  • 我使用了最终的脚本,它运行得非常完美,而不是unnest,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-20
  • 1970-01-01
相关资源
最近更新 更多