如何在 PostgreSQL 循环中使用 FOREACH
Posted
技术标签:
【中文标题】如何在 PostgreSQL 循环中使用 FOREACH【英文标题】:How to use FOREACH in a PostgreSQL LOOP 【发布时间】:2022-01-24 00:16:08 【问题描述】:我正在尝试编写一个非常简单的 pgsql 语句来遍历一个简单的状态缩写数组。
CREATE OR REPLACE FUNCTION my_schema.showState()
RETURNS text AS
$$
DECLARE
my_array text[] := '["az","al", "ak", "ar"]'
BEGIN
FOREACH state IN my_array
LOOP
RETURN SELECT format('%s', state);
END LOOP;
END;
$$ LANGUAGE plpgsql;
SELECT * FROM showState();
我正在使用 PostgresSQL 版本 11+。我一直收到错误ERROR: syntax error at or near "BEGIN"
我想在这里看到的输出现在只是看到结果窗口中打印的状态缩写。像这样:
我在这里做错了什么?
【问题讨论】:
Edit 这个问题展示了 beforeFOREACH
是什么。理想情况下显示整个函数/过程/DO
/...
而且你不能只在PL/pgSQL
中的SELECT
没有选择的数据到某个地方(变量、返回缓冲区,...)。所以你的无目标SELECT
将是下一个问题。
请向我们展示您完整的存储过程(或函数)。你到底想在这里实现什么?你期望的输出是什么?
该代码不会产生您发布的错误。见dbfiddle.uk/…。如果您需要帮助,您真的应该发布产生错误的代码。
已经有内置函数了:unnest()
:dbfiddle.uk/…
【参考方案1】:
在my_array text[] := '["az","al", "ak", "ar"]'
之后缺少;
。
'["az","al", "ak", "ar"]'
不是有效的数组字面量。
如果你想要一个集合返回函数,你需要将它的返回类型声明为SETOF
。
FOREACH
的头部缺少 ARRAY
关键字。
state
必须声明。
您需要使用RETURN NEXT ...
将值推送到要返回的集合中。
format()
在这里毫无意义,它实际上没有任何作用。
所有这些都得到纠正后,你会得到以下内容:
CREATE
OR REPLACE FUNCTION showstate()
RETURNS SETOF text
AS
$$
DECLARE
my_array text[] := ARRAY['az',
'al',
'ak',
'ar'];
state text;
BEGIN
FOREACH state IN ARRAY my_array
LOOP
RETURN NEXT state;
END LOOP;
END;
$$
LANGUAGE plpgsql;
db<>fiddle
【讨论】:
效果很好!为之前的错误道歉;我正在学习这个。我确实有一个后续问题:假设不是只返回文本,我希望它运行另一个函数,该函数将状态作为参数,如下所示:SELECT * my_schema_my_function(state)
。我将如何更改上述内容? (例如:RETURNS void
... LOOP SELECT * my_schema_my_function(state END LOOP;
这行得通吗?
@gwydion93:标量函数?只需在返回之前将其应用于state
:RETURN NEXT my_schema.my_function(state);
(尽管我开始怀疑您在不需要它们的地方使用函数,并且简单的集合操作会更好......)。但一般来说,每个线程一个问题。如果您还有其他问题,请打开一个新问题。
谢谢;如果我找不到合适的解决方案,我可能会添加一个单独的问题来解决这个问题。我的目标是遍历状态缩写数组并运行一个函数,该函数根据输入状态参数创建一个表。试图自动化这个过程,这样我就不必为每个状态手动运行它。
@gwydion93:嗯,这里只是一个旁注,但是,是的,或者更糟糕的是,这听起来很可疑,就像你正在接受一个非常非常糟糕的数据库设计,这会导致你很多未来的痛苦。我怀疑一个州的每个这样的表看起来都一样并且包含相同类型的数据?然后恰好有 一个 表,用于所有状态的所有数据。只需在该表中有一个额外的列来指定行所属的状态。以上是关于如何在 PostgreSQL 循环中使用 FOREACH的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 postgresql 中使用 for 循环(功能)[重复]