Postgres函数返回表不返回列中的数据

时间:2013-01-31 15:01:29

标签: sql postgresql plpgsql postgresql-9.1

我有一个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函数不会将数据作为列返回?

2 个答案:

答案 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 (...)参数的参数。
  • 不要在Postgres中使用不带引号的CaMeL案例标识符。它可以工作,不带引号的标识符可以转换为小写,但它会导致混淆错误。看到

临时表在示例中完全没用(可能过度简化)。你可以减少到:

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
(...)