如何在 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 函数中返回表及其总数的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Postgres 11 函数(存储过程)在某个时区返回 $TIMESTAMP 或之前的最新行?

如何在 Postgres 函数中使用文本输入作为列名?

在 Postgres 中,如何在更改表后重新验证(“类型检查”)函数和过程?

R:如何使用 dplyr(函数 scr_postgres)从 redshift 中的模式中选择表?

如何在 Postgres 中使用 Plpython3 返回结果集

如何计算具有窗口函数的过滤器的总数?