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 into
:https://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
$$;
正在创建函数 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 into
:https://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
$$;