tin*_*lyx 2 postgresql plpgsql
我正在尝试使用返回表的PL/pgSQL(PostgreSQL 9.3)函数编写循环.我RETURN NEXT;在循环中的每个查询后都没有使用参数,下面的示例如plpgsql错误"RETURN NEXT在表返回函数中没有函数和OUT参数",以及其他地方.但是,我仍然收到一条错误消息:
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
Run Code Online (Sandbox Code Playgroud)
下面是重现问题的最小代码示例.任何人都可以请帮助解释如何修复测试代码以返回表格?
提前致谢.
最小的例子:
CREATE OR REPLACE FUNCTION test0()
RETURNS TABLE(y integer, result text) AS $func$
DECLARE
yr RECORD;
BEGIN
FOR yr IN SELECT * FROM generate_series(1,10,1) AS y_(y)
LOOP
RAISE NOTICE 'Computing %', yr.y;
SELECT yr.y, 'hi';
RETURN NEXT;
END LOOP;
RETURN;
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
给出的示例可以完全替换为RETURN QUERY:
BEGIN
RETURN QUERY SELECT y_.y, 'hi' FROM generate_series(1,10,1) AS y_(y)
END;
Run Code Online (Sandbox Code Playgroud)
这将是一个很大更快.
通常,您应该尽可能避免迭代,而是支持面向集合的操作.
在return next循环中不可避免的情况(这是非常罕见的,并且大多数情况下仅限于需要异常处理时),您必须设置OUT参数值或表参数,然后return next不带参数.
在这种情况下,你的问题是SELECT yr.y, 'hi';没有做任何事情的线.您假设a的隐式目标SELECT是out参数,但事实并非如此.您必须使用out参数作为循环变量,如@peterm,使用赋值或使用SELECT INTO:
FOR yr IN SELECT * FROM generate_series(1,10,1) AS y_(y)
LOOP
RAISE NOTICE 'Computing %', yr.y;
y := yr.y;
result := 'hi';
RETURN NEXT;
END LOOP;
RETURN;
Run Code Online (Sandbox Code Playgroud)
@Craig已经解释过了。
另外,如果你真的需要一个循环,你可以让这个更简单/更便宜。您不需要声明额外的记录变量并重复分配。plpgsql 中的赋值相对昂贵。直接赋值给OUT声明的变量RETURNS TABLE。这些在代码中随处可见,FOR循环也可以分配给变量列表。手册:
目标是记录变量、行变量或逗号分隔的标量变量列表。
创建或替换函数 test0() 返回表(y 整数,结果文本) 语言 plpgsql AS $函数$宣布 年记录;-- 现在不需要了 开始 FOR y,结果 IN 选择 g, 'text_'::text || G 来自generate_series(1,10) g 环形 发出通知“计算%”,y; 返回下一个; 结束循环; 结尾 $函数$;
不要使用标识符y两次(作为OUT参数和列别名),而您可以轻松避免它。那是一把上了膛的步枪。如果无法避免这种情况,请对列进行表限定。
没有参数的决赛RETURN是很好的形式,但完全是可选的。当控制到达final时END,自动返回完整的结果。
gin自动FROM generate_series(1,10) g是表别名和列别名,除非给出显式列别名。它实际上与 相同FROM generate_series(1,10) g(g)。
一种方法可以做到这一点
CREATE OR REPLACE FUNCTION test0()
RETURNS TABLE(y integer, result text) AS $$
BEGIN
FOR y, result IN
SELECT s.y, 'hi' result FROM generate_series(1,10,1) AS s(y)
LOOP
RETURN NEXT;
END LOOP;
END
$$ LANGUAGE plpgsql;
SELECT * FROM test0();
Run Code Online (Sandbox Code Playgroud)
结果:
| 是 | 结果 | |----|--------| | 1 | 你好| | 2 | 你好| | 3 | 你好| | 4 | 你好| | 5 | 你好| | 6 | 你好| | 7 | 你好| | 8 | 你好| | 9 | 你好| | 10 | 10 你好|
这是一个SQLFiddle演示