如何在 postgres 函数中返回表及其总数

Posted

技术标签:

【中文标题】如何在 postgres 函数中返回表及其总数【英文标题】:How to return a table and its total count in postgres' function 【发布时间】:2020-02-12 10:28:47 【问题描述】:

我是 postgresql 的新手,并创建如下函数

CREATE OR REPLACE FUNCTION GetLogs(
    _from Date, 
    _to Date,  
    _sortBy TEXT, 
    _orderby INT, 
    _page INT, 
    _row INT)
 RETURNS TABLE (
     "Id" UUID, 
     "RequestHeaders" text, 
     "RequestContent" text, 
     "ResponseHeaders" text, 
     "ResponseContent" text, 
     "ResponseCode" integer, 
     "ExecutionTimeMs" integer, 
     "Description" text,
     "RecordedOn" timestamp with time zone, 
     "Username" character varying, 
     "Exception" text) 
AS $$
BEGIN
    RETURN QUERY 
        SELECT COUNT(1)
        FROM dbo."Logs" log
        where log."RecordedOn" >= $1 and log."RecordedOn" <= $2;

    RETURN QUERY 
        SELECT log.*
        FROM dbo."Logs" log
        where log."RecordedOn" >= $1 and log."RecordedOn" <= $2
        Offset ($5-1) * $6
        Limit $6;
END;
$$ LANGUAGE plpgsql;

,并使用

调用它
select * from GetLogs('2020-02-11','2020-02-12','Date',0,1,10)

我希望这将是一个计数和表格数据,但错误是

ERROR:  structure of query does not match function result type
DETAIL:  Returned type bigint does not match expected type uuid in column 1.

有人能解决吗?

【问题讨论】:

第一个RETURN QUERY 仍然需要返回您定义该函数返回的结构。相反,您返回一个 BIGINT。您希望从这个函数中得到什么格式?显示一个示例,其中包含您希望从函数调用中获得的输出。 【参考方案1】:

您不能返回结构与 RETURNS TYPE 不匹配的结果(在您的情况下 - 桌子)。 相反,您可以使用窗口函数将RowsCount 添加到每个返回的行。

CREATE OR REPLACE FUNCTION GetLogs(
    _from Date, 
    _to Date,  
    _sortBy TEXT, 
    _orderby INT, 
    _page INT, 
    _row INT)
 RETURNS TABLE (
     "Id" UUID, 
     "RequestHeaders" text, 
     "RequestContent" text, 
     "ResponseHeaders" text, 
     "ResponseContent" text, 
     "ResponseCode" integer, 
     "ExecutionTimeMs" integer, 
     "Description" text,
     "RecordedOn" timestamp with time zone, 
     "Username" character varying, 
     "Exception" text,
     "RowsCount" integer
)
AS $$
DECALARE
    RowsCount integer;
BEGIN

    RETURN QUERY 
        SELECT log.*, COUNT(*) OVER() AS RowsCount
        FROM dbo."Logs" log
        WHERE log."RecordedOn" >= $1 AND log."RecordedOn" <= $2
        OFFSET ($5-1) * $6
        LIMIT $6;
END;
$$ LANGUAGE plpgsql;

【讨论】:

可以返回多个结果吗? 我不确定是否可以返回 2 个不同类型的结果

以上是关于如何在 postgres 函数中返回表及其总数的主要内容,如果未能解决你的问题,请参考以下文章