PL/PgSql 动态 select 查询未返回数据

PL/PgSql Dynamic select query not returning data

正在创建函数 return 来自现有 table 的一些数据。 我根据 运行 时间传递的函数参数动态地为 select 查询构建 schema.table,但是在调用函数时它 return 什么都没有。

下面的代码

DROP TYPE IF EXISTS metadata.RETURNED_DATA CASCADE;

CREATE TYPE metadata.RETURNED_DATA AS
(
    postal_id          BIGINT,
    postal_code        VARCHAR(15),
    admin_id   BIGINT,
    admin_code VARCHAR(11)
);

DROP FUNCTION IF EXISTS metadata.pc_get_data(VARCHAR, VARCHAR, VARCHAR);

CREATE OR REPLACE FUNCTION metadata.pc_get_data(reg CHARACTER VARYING, iso CHARACTER VARYING,
                                                        pcode CHARACTER VARYING
) RETURNS SETOF metadata.RETURNED_DATA

    LANGUAGE plpgsql
AS
$$

BEGIN

    EXECUTE FORMAT(
            'SELECT postal_id,
                   postal_code,
                   admin_id,
                   admin_code
            FROM %I_content.%I_pc_aet_data
            WHERE postal_code = %L', reg, iso, pcode);

END

$$;

SELECT *
FROM pc_get_data('aaa', 'bbb', '12345'); 

我不熟悉这个语法,现在没有办法测试它,所以,如果我的回答有误,请告诉我,我会edit/remove。

根据文档,您可以执行 select intohttps://www.postgresql.org/docs/9.1/plpgsql-statements.html

示例:

EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by =  AND inserted <= '
   INTO c
   USING checked_user, checked_date;

也许您可以执行以下操作(未经测试):


DROP FUNCTION IF EXISTS metadata.pc_get_data(VARCHAR, VARCHAR, VARCHAR);

CREATE OR REPLACE FUNCTION metadata.pc_get_data(reg CHARACTER VARYING, iso CHARACTER VARYING,
                                                        pcode CHARACTER VARYING
) RETURNS SETOF metadata.RETURNED_DATA

    LANGUAGE plpgsql
AS
$$

BEGIN

    EXECUTE FORMAT(
            'SELECT postal_id,
                   postal_code,
                   admin_id,
                   admin_code
            INTO TEMP TABLE my_temp
            FROM %I_content.%I_pc_aet_data
            WHERE postal_code = %L', reg, iso, pcode);

            `SELECT * FROM my_temp;

END

$$;

您不能 return 来自 EXECUTE 的值,除非您使用 SELECT...INTO

可以在 PostgreSQL wiki

中找到很好的示例

尝试使用 text 数据类型。
--https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_varchar.28n.29_by_default

CREATE TYPE metadata.RETURNED_DATA AS
(
    postal_id          BIGINT,
    postal_code        text,
    admin_id   BIGINT,
    admin_code text
);

 CREATE OR REPLACE FUNCTION metadata.pc_get_data(reg text, iso text, pcode text
    ) RETURNS SETOF aaa_content.RETURNED_DATA
        LANGUAGE plpgsql
    AS
    $$
    BEGIN
    return query execute FORMAT(
    'SELECT postal_id,
    postal_code,
    admin_id,
    admin_code
    FROM %I_content.%I_pc_aet_data
    WHERE postal_code = %L', reg, iso, pcode);
    END
    $$;

小心复合类型

按照@jjanes 的建议添加 'RETURN QUERY EXECUTE' 评论解决了缺失的部分。

下面是最终的代码片段。

DROP FUNCTION IF EXISTS metadata.pc_get_data(VARCHAR, VARCHAR, VARCHAR);

CREATE OR REPLACE FUNCTION metadata.pc_get_data(reg CHARACTER VARYING, iso CHARACTER VARYING,
                                                        pcode CHARACTER VARYING
) RETURNS SETOF metadata.RETURNED_DATA

    LANGUAGE plpgsql
AS
$$

BEGIN
     RETURN QUERY -- ## the missing part ## 

    EXECUTE FORMAT(
            'SELECT postal_id,
                   postal_code,
                   admin_id,
                   admin_code
            INTO TEMP TABLE my_temp
            FROM %I_content.%I_pc_aet_data
            WHERE postal_code = %L', reg, iso, pcode);

            `SELECT * FROM my_temp;

END

$$;