我有一个Postgres函数,它返回一个表:
CREATE OR REPLACE FUNCTION testFunction() RETURNS TABLE(a int, b int) AS
$BODY$
DECLARE a int DEFAULT 0;
DECLARE b int DEFAULT 0;
BEGIN
CREATE TABLE tempTable AS SELECT a, b;
RETURN QUERY SELECT * FROM tempTable;
DROP TABLE tempTable;
END;
$BODY$
LANGUAGE plpgsql;
此函数不以行和列形式返回数据。相反,它将数据返回为:
(0,0)
这导致Coldfusion cfquery块在提取数据时出现问题。从此函数返回表时,如何获取行和列中的数据?换句话说:为什么PL / pgSQL函数不会将数据作为列返回?
答案 0 :(得分:19)
要获取单个列而不是行类型,请使用以下命令调用该函数:
SELECT * FROM testfunction();
就像你从表中选择所有列一样 还要考虑这个评估的测试函数形式:
CREATE OR REPLACE FUNCTION testfunction()
RETURNS TABLE(a int, b int) AS
$func$
DECLARE
_a int := 0;
_b int := 0;
BEGIN
CREATE TEMP TABLE tbl AS SELECT _a, _b;
RETURN QUERY SELECT * FROM tbl;
DROP TABLE tempTable;
END
$func$ LANGUAGE plpgsql;
特别是:
DECLARE
关键字只需要一次。OUT
子句中声明已经(隐式)声明为RETURNS TABLE (...)
参数的参数。临时表在示例中完全没用(可能过度简化)。你可以减少到:
CREATE OR REPLACE FUNCTION testfunction(OUT a int, OUT b int) AS
$func$
BEGIN
a := 0;
b := 0;
END
$func$ LANGUAGE plpgsql;
答案 1 :(得分:4)
当然,您可以通过将函数调用放在FROM
子句中来完成此操作,就像正确回答了Eric Brandstetter一样。
但是,这有时会使FROM子句中已经包含其他内容的查询变得复杂。
要获取函数返回的各个列,可以使用以下语法:
SELECT (testfunction()).*
或者仅获取名为“ a”的列:
SELECT (testfunction()).a
将整个函数(包括输入值)用括号括起来,后跟一个点和所需的列名或一个星号。
要获取函数返回的列名,您必须:
SELECT * FROM testfunction()
。 输入值仍可以来自FROM
子句。
为了说明这一点,请考虑以下功能并测试数据:
CREATE FUNCTION funky(a integer, b integer)
RETURNS TABLE(x double precision, y double precision) AS $$
SELECT a*random(), b*random();
$$ LANGUAGE SQL;
CREATE TABLE mytable(a integer, b integer);
INSERT INTO mytable
SELECT generate_series(1,100), generate_series(101,200);
您可以调用函数“ funky(a,b)”,而无需将其放在FROM
子句中:
SELECT (funky(mytable.a, mytable.b)).*
FROM mytable;
这将导致2列:
x | y
-------------------+-------------------
0.202419687062502 | 55.417385618668
1.97231830470264 | 63.3628275180236
1.89781916560605 | 1.98870931006968
(...)