【发布时间】:2018-07-04 22:13:54
【问题描述】:
我想使用函数/过程向“模板”表中添加具有多个值的附加列(例如期间名称),并对行进行笛卡尔积,因此我的“模板”与为新列提供了不同的值。
例如在我的template_country_channel 表中添加一个包含 2 个值的期间列:
SELECT *
FROM unnest(ARRAY['P1', 'P2']) AS prd(period)
, template_country_channel
ORDER BY period DESC
, sort_cnty
, sort_chan;
/*
-- this is equivalent to:
(
SELECT 'P2'::text AS period
, *
FROM template_country_channel
) UNION ALL (
SELECT 'P1'::text AS period
, *
FROM template_country_channel
)
--
*/
此查询运行良好,但我想知道是否可以将其转换为 PL/pgSQL 函数/过程,提供要添加的新列值、要添加额外列的列(并可选择指定顺序按条件)。
我想做的是:
SELECT *
FROM template_with_periods(
'template_country_channel' -- table name
, ARRAY['P1', 'P2'] -- values for the new column to be added
, 'period DESC, sort_cnty, sort_chan' -- ORDER BY string (optional)
);
并且与第一个查询具有相同的结果。
所以我创建了一个类似的函数:
CREATE OR REPLACE FUNCTION template_with_periods(template regclass, periods text[], order_by text)
RETURNS SETOF RECORD
AS $BODY$
BEGIN
RETURN QUERY EXECUTE 'SELECT * FROM unnest($2) AS prd(period), $1 ORDER BY $3' USING template, periods, order_by ;
END;
$BODY$
LANGUAGE 'plpgsql'
;
但是当我跑步时:
SELECT *
FROM template_with_periods('template_country_channel', ARRAY['P1', 'P2'], 'period DESC, sort_cnty, sort_chan');
我有错误ERROR: 42601: a column definition list is required for functions returning “record”
经过一番谷歌搜索,似乎我需要定义列和类型的列表来执行RETURN QUERY(正如错误消息所准确指出的那样)。
不幸的是,整个想法是将该函数与许多“模板”表一起使用,因此列名和类型列表不固定。
- 还有其他方法可以尝试吗?
- 或者是让它工作的唯一方法是在函数内有一种方法来获取
template表的列名和类型列表?
【问题讨论】:
-
整个想法是将该函数与许多“模板”表一起使用,因此列名和类型列表不固定——这不是问题:@987654329 @您需要在调用方 f.ex 上登记列名和类型。
select * from template_with_periods(...) as t(period text, sort_cnty int, sort_chan text) -
实际上这意味着我必须在编写查询时指定列名/类型,并且我必须知道每个表结构——非常乏味,而这正是我想要避免的(如果 pgsql 允许)。
-
不,很遗憾,它不允许这样做。您需要定义输出的 exact 结构。在函数定义中,或者在调用方(使用
RETURNS SETOF RECORD)。
标签: postgresql plpgsql