我想从plpgsql函数返回表。
这是我的代码。
CREATE FUNCTION test() RETURNS my_table AS
$BODY$DECLARE
q4 my_table;
BEGIN
q4 := SELECT * FROM my_table;
RETURN q4;
END;$BODY$
LANGUAGE sql;
我收到以下错误:
Error: ERROR: syntax error at or near "SELECT"
LINE 5: q4 := SELECT * FROM my_table;
我从这个问题/教程开始。 https://dba.stackexchange.com/questions/35721/declare-variable-of-table-type-in-pl-pgsql&& http://postgres.cz/wiki/PL/pgSQL_%28en%29
我的想法是我需要将此查询分配给变量。这只是我想要创建的函数的一小部分。
第二个问题是如何遍历该集合并进行一些数学运算并将值赋给该表的某个字段。 但首先我想解决这个问题。
答案 0 :(得分:3)
CREATE FUNCTION test()
RETURNS my_table AS
$BODY$
DECLARE
q4 my_table;
BEGIN
-- add brackets to get a value
-- select row as one value, as q4 is of the type my_table
-- and limit result to one row
q4 := (SELECT my_table FROM my_table ORDER BY 1 LIMIT 1);
RETURN q4;
END;$BODY$
-- change language to plpgsql
LANGUAGE plpgsql;
sql
函数中使用变量,请使用plpgsql
。select query
则返回行集。使用循环的示例:
DROP FUNCTION test();
CREATE FUNCTION test()
-- change to SETOF to return set of rows, not a single row
RETURNS SETOF my_table AS
$BODY$
DECLARE
q4 my_table;
BEGIN
FOR q4 in
SELECT * FROM my_table
LOOP
RETURN NEXT q4;
END LOOP;
END;$BODY$
LANGUAGE plpgsql;
SELECT * FROM test();
的文档
答案 1 :(得分:3)
PostgreSQL没有表变量。所以你不能通过任何变量返回表。创建任何表时,PostgreSQL会创建具有相同名称的复合类型。但它不是表类型 - 它是复合类型 - 记录。
CREATE TABLE xx(a int, b int);
CREATE OR REPLACE FUNCTION foo()
RETURNS xx AS $$
DECLARE v xx;
BEGIN
v := (10,20);
RETURN v;
END;
$$ LANGUAGE plpgsql;
函数foo
返回复合值 - 它不是表。但是你可以编写一些返回复合值集的函数 - 它就是表。
CREATE OR REPLACE FUNCTION foo(a int)
RETURNS SETOF xx AS $$
DECLARE v xx;
BEGIN
FOR i IN 1..a LOOP
v.a := i; v.b := i+1;
RETURN NEXT v;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
postgres=# SELECT * FROM foo(3);
┌───┬───┐
│ a │ b │
╞═══╪═══╡
│ 1 │ 2 │
│ 2 │ 3 │
│ 3 │ 4 │
└───┴───┘
(3 rows)
如果结果基于查询,则可以使用RETURN QUERY
。它比FOR IN SELECT
和RETURN NEXT
更快,更短,更易读:
CREATE OR REPLACE FUNCTION foo2(a int)
RETURNS SETOF xx AS $$
BEGIN
RETURN QUERY SELECT * FROM xx
WHERE xx.a = foo2.a;
RETURN;
END;
$$ LANGUAGE plpgsql;
仔细使用这些功能。它们是优化器的黑盒子,因此优化器不能同时优化函数和外部查询中的查询,它必须单独优化这些查询,这对于某些复杂查询不应该有效。当外部查询很简单时,它应该不是问题。
答案 2 :(得分:1)
对于最初的OP来说可能为时已晚,但可能会帮助其他人。您只需返回SETOF表格类型即可。我修改了原始代码作为示例。
CREATE FUNCTION test() RETURNS SETOF my_table AS
$$
DECLARE
q4 my_table;
BEGIN
FOR q4 IN SELECT * FROM my_table LOOP
RETURN NEXT q4;
END LOOP
END;
$$
LANGUAGE plpgsql;