在 Pl/pgSQL 中使用 FOR 循环时,它在 Postgres 11.8 中不起作用
Posted
技术标签:
【中文标题】在 Pl/pgSQL 中使用 FOR 循环时,它在 Postgres 11.8 中不起作用【英文标题】:FOR-loop does NOT work in Postgres 11.8 when using it in Pl/pgSQL 【发布时间】:2020-06-19 08:05:42 【问题描述】:我正在这个link 和this 上尝试来自PostgreSQLTutorial 网站的FOR 循环示例,this 是正在使用的示例数据库。问题是我无法开始工作是以下 for-loop 示例:
CREATE OR REPLACE FUNCTION for_loop_through_query(
n INTEGER DEFAULT 10
)
RETURNS VOID AS $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT title
FROM film
ORDER BY title
LIMIT n
LOOP
RAISE NOTICE '%', rec.title;
END LOOP;
END;
$$ LANGUAGE plpgsql;
当我运行select for_loop_through_query(5);
时,我根本没有得到任何结果!
我试过在 DataGrip 和 pgAdmin4 中运行它,PostgreSQL 版本是 11.8 在 Fedora 30 操作系统上。我还尝试用int
而不是INTEGER
替换n 参数类型。 我是否遗漏了什么(命令/附加设置)?非常感谢任何帮助/建议。
P.S.在他们的website 上说已经安装了 PostgreSQL 11.3,所以我猜他们的示例必须在不比我的旧版本那么多的 PostgreSQL 上运行。
更新1: 例外的输出应该是:
注意:学院恐龙 注意:王牌金手指 注意:适应孔 注意:外遇偏见 注意:非洲鸡蛋
我得到的输出:
postgres=# select * FROM version();
version
--------------------------------------------------------------------------------------------------------
PostgreSQL 11.8 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2), 64-bit
(1 row)
... 当我执行 2 个以下命令时
sudo su - postgres
和
psql dvdrental postgres
我得到这个输出:
dvdrental=# select for_loop_through_query(5);
NOTICE: Academy Dinosaur
NOTICE: Ace Goldfinger
NOTICE: Adaptation Holes
NOTICE: Affair Prejudice
NOTICE: African Egg
for_loop_through_query
------------------------
(1 row)
在 DataGrip 和 pgAdmin4 中调用此函数时似乎有什么问题......有什么想法吗?
【问题讨论】:
【参考方案1】:使用 PostgreSQL 11.8,如果表中有数据,它就可以工作。
请注意,您的函数返回 void
,因此您没有真正的结果集:函数应该返回一些数据,否则您可以使用过程。
select * from version();
version
--------------------------------------------------------------------------------
-------------------------
PostgreSQL 11.8 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (R
ed Hat 4.8.5-39), 64-bit
(1 row)
select * from film;
title
-------
ABC0
ABC1
ABC2
ABC3
ABC4
ABC5
ABC6
ABC7
ABC8
(9 rows)
CREATE OR REPLACE FUNCTION for_loop_through_query(
n INTEGER DEFAULT 10
)
RETURNS VOID AS $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT title
FROM film
ORDER BY title
LIMIT n
LOOP
RAISE NOTICE '%', rec.title;
END LOOP;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
select * from for_loop_through_query(5);
NOTICE: ABC0
NOTICE: ABC1
NOTICE: ABC2
NOTICE: ABC3
NOTICE: ABC4
for_loop_through_query
------------------------
(1 row)
select for_loop_through_query(5);
NOTICE: ABC0
NOTICE: ABC1
NOTICE: ABC2
NOTICE: ABC3
NOTICE: ABC4
for_loop_through_query
------------------------
(1 row)
由于您的函数不返回任何数据,您可以在 pgAdmin4 仅在 Messages
选项卡中获得 RAISE NOTICE 消息:
NOTICE: ABC0
NOTICE: ABC1
NOTICE: ABC2
NOTICE: ABC3
NOTICE: ABC4
NOTICE: ABC5
NOTICE: ABC6
NOTICE: ABC7
NOTICE: ABC8
Successfully run. Total query runtime: 54 msec.
1 rows affected.
【讨论】:
但我确实在表中有数据 请使用psql
发布您的输出并详细说明您的预期输出:通知消息?函数结果?
更新了我的问题,正如您在上一条评论中提出的,请看一下
要在客户端应用程序中拥有RAISE NOTICE
消息,您需要有一个能够从数据库端检索此数据的应用程序:pgAdmin 知道如何执行此操作,但我无法告知数据网格(RAISE NOTICE
消息与SELECT
语句等通常 DML 返回的数据不同。
true,我已经在 DataGrip 中检查了类似的“消息”选项卡/选项(如在 pgAdmin4 中),并且它确实以“输出”控制台的形式...显然我已经监督它向我展示了 ResultSet 的附加选项卡。再一次感谢你。 :)以上是关于在 Pl/pgSQL 中使用 FOR 循环时,它在 Postgres 11.8 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
PL/pgSQL“for循环”+选择基本示例(“hello world”)
PostgreSQL vs Oracle:PL/pgSQL 的“编译时”检查