如何在函数中返回动态列数?

Posted

技术标签:

【中文标题】如何在函数中返回动态列数?【英文标题】:How return dynamic number of columns in function? 【发布时间】:2019-07-26 11:10:25 【问题描述】:

PostgreSQL 11 数据库中,我有 6 列的表。 Next 函数返回已定义列的静态数量。

CREATE FUNCTION CALCULATION(INTEGER)
RETURNS TABLE(
    ORGANIZATION_ID INT4,
    ORGANIZATION_NAME VARCHAR,
    ORGANIZATION_RANG INT4,
    PARENT_ORGANIZATION_ID INT4,
    PARENT_ORGANIZATION_NAME VARCHAR,
    PARENT_ORGANIZATION_RANG INT4
) AS $$
    SELECT * FROM ANALYTICS;
$$ LANGUAGE SQL;

如何在 Postgres 11 中创建一个 SQL 函数,根据传入的参数返回具有动态列数的结果集?

例如,如果我调用SELECT * FROM CALCULATION(2);,函数会返回前 2 列。

如果使用 SQL 函数无法做到这一点,是否可以使用 PL/pgSQL 函数?

【问题讨论】:

不,这在 Postgres 中是不可能的。在这些情况下,我倾向于将“动态列”作为单个 JSON 值返回 - 也许这对您也有用? @a_horse_with_no_name 听起来很有趣,你能发个例子吗? 如果您提供更多关于您需要什么样的“动态列”以及如何计算它们的详细信息。 @a_horse_with_no_name 正如我之前所说的,在我的情况下,ANALYTICS 表有 6 列。例如,如果我在函数中将2 作为参数传递,我想要这样的json ["organization_id": 15, "organization_name": "Google", "organization_id": 16, "organization_name": "Apple", "organization_id": 17, "organization_name": "Tesla"]。换句话说,一个对象数组。每个对象对应于数据库中的一条记录。由于我将 2 作为参数传递,因此每个对象内将有 2 列。希望你能理解我。 听起来您总是想选择可用列的子集。那么 Morris de Oryx 的答案似乎就是您要寻找的。​​span> 【参考方案1】:

这对于 RECORD 返回函数是可能的。

CREATE FUNCTION calculation(how_many integer) RETURNS SETOF RECORD
LANGUAGE plpgsql
AS $fff$
BEGIN
    IF how_many = 1
        THEN RETURN QUERY SELECT 'foo'::text;
    ELSIF how_many = 2
        THEN RETURN QUERY SELECT 'foo'::text, 'bar'::text;
    END IF;
END;
$fff$
;

现在你可以这样做了:

jbet=> SELECT * FROM calculation(1) AS f(first_col text);
 first_col
-----------
 foo
(1 row)

jbet=> SELECT * FROM calculation(2) AS f(first_col text, second_col text);
 first_col | second_col
-----------+------------
 foo       | bar
(1 row)

非常严重的缺点是每次调用函数时都必须定义一组返回的列,所以我认为这个答案对你没有用处:)

无论如何,Postgresql 在运行查询之前需要知道每个 SELECT 的返回类型,因此您必须以一种或其他方式定义列。

如果您只想要数据而不关心是否有单独的列,JSON 返回值可能是一个合理的答案。

【讨论】:

【参考方案2】:

备份一个步骤,为什么不使用标准选择从您的集合返回函数中获取您想要的列?

select organization_name,
       organization_rang,
       parent_organization_name,
       parent_organization_rang

  from calculation();

这很容易理解和灵活。我猜您已经编写了一个简化的示例,并且有充分的理由说明您的要求……但我想我会仔细检查。

【讨论】:

以上是关于如何在函数中返回动态列数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Postgresql 交叉表中获取动态列数

如何在 C++ 中获取二维动态数组的行数和列数

matlab中的length表示啥?应该如何使用?

如何在 NativeScript 中创建具有动态行数和列数的表?

如何在工作表中动态创建具有列数的数组,以删除多列中的重复项

如果是varchar2如何执行动态sql