如何从Postgres函数返回结果表?

时间:2016-09-09 20:28:41

标签: sql postgresql function plpgsql

我有从SQL Server转换为Postgres的函数脚本,现在当我运行该函数时出现错误

  

错误:查询结构与函数结果类型

不匹配

我的函数获取3个参数(account TransactionDate TransactionTime Code TransactionSequence CurrentStatus TransactionAmount 8246 2015-11-02 6615 RT 3 00047 -808.21 8246 2015-11-02 6615 ITD 2 00082 NULL 8246 2015-11-02 6615 PT 1 00082 808.21 8246 2015-11-02 6616 RT 3 00082 -808.21 8246 2015-11-02 6616 ITR 2 03058 NULL 8246 2015-11-02 6616 PT 1 03058 808.21 8246 2015-11-05 9600 E56 2 03058 -121.94 ),并且应该返回一个我包含在代码中的表。我使用"返回查询"。

我正在执行我的功能:

siteid bigint, datefrom timestamp, dateto timestamp

如何从我的函数中将此结果作为表格获取?

这是我的功能的截图

getrtbactivesiteplaces(1475, '2016-02-01', '2016-08-01')

2 个答案:

答案 0 :(得分:0)

您的函数的返回类型为setof varchar,但它应该是这样的:

RETURNS TABLE (Id              integer,
               RtbActiveSiteId integer,
               ... etc ...
              )

答案 1 :(得分:0)

您的代码存在两个问题,我有两条改进建议。

首先,您应该RETURNS SETOF varchar指定函数返回的所有列,而不是RETURNS TABLE ...。其次,您有三个函数参数,您在功能块中重新声明其名称,屏蔽参数值。这就是函数没有返回任何原因,因为没有使用参数值。

第三,我把所有的总和放在一个子查询中,这个查询更简单,也可能更高效。最后,由于函数体是单个SQL语句,因此您应该将其设置为SQL函数,这比PL / pgSQL语言函数更有效。

见下文。

CREATE OR REPLACE FUNCTION "whis2011"."getrtbactivesiteplaces"
    (IN siteid int8, IN datefrom timestamp, IN dateto timestamp)
RETURNS SETOF "varchar" TABLE (id int, RtbActiveSiteId int, ...) -- add all fields
AS $BODY$
DECLARE
siteid BIGINT;
datefrom timestamp without time zone;
dateto   timestamp without time zone; -- don't redeclare parameters!!!
BEGIN -- not needed for a SQL function
    -- Insert statements for procedure here
    RETURN QUERY SELECT pl."Id", -- SQL function uses simple SELECT
        pl."RtbActiveSiteId",
        pl."AdPlaceId",
        pl."AdPosition",
        pl."Ctr",
        pl."State",
        pl."BidPrice",
        pl."MinBidFloor",
        pl."MinBidFloorCurrency",
        pl."AverageCpm",
        pl."AverageClickCost",
        ss.*
    FROM "whis2011"."RtbActiveSitePlaces" pl
    LEFT JOIN (
        SELECT "RtbActiveSitePlaceId" AS "Id"
               coalesce(SUM("BidsCount"),0) AS BidsCount,
               coalesce(SUM("ShowsCount"),0) AS ShowsCount,
               coalesce(SUM("RealShowsCount"),0) AS RealShowsCount,
               coalesce(SUM("ClicksCount"),0) AS ClicksCount,
               coalesce(SUM("ClickLayerClicksCount"),0) as ClickLayerClicksCount,
               coalesce(SUM("ShowsCost"),0::money) AS ShowsCost,
               coalesce(SUM("ClicksCost"),0::money) AS ClicksCost,
               coalesce(SUM("BidsCost"),0::money) AS BidsCost,
               coalesce(SUM("SliderMovesCount"),0) AS SliderMovesCount
         FROM "whis2011"."RtbActiveSitePlaceStatistics"
         WHERE "Date" >= datefrom AND "Date" < dateto
         GROUP BY "RtbActiveSitePlaceId") ss USING ("Id")
    WHERE pl."RtbActiveSiteId" = siteid;
END;  -- not needed for a SQL function
$BODY$ LANGUAGE sql STRICT STABLE; -- don't call on NULL input and use STABLE

然后你可以这样调用这个函数:

SELECT * FROM getrtbactivesiteplaces(1475, '2016-02-01', '2016-08-01');