我想使用函数/程序添加到'模板'使用多个值列出一个附加列(例如句点名称),并在行上执行笛卡尔积,这样我的模板就可以了。与为新列提供的不同值重复。
E.g。将包含2个值的句点列添加到template_country_channel
表:
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
表的名称和类型?答案 0 :(得分:0)
如果您希望输出列列表完全动态,则我用refcursor
进行了此操作:
CREATE OR REPLACE FUNCTION is_record_exists(tablename character varying, columns character varying[], keepcolumns character varying[] DEFAULT NULL::character varying[])
RETURNS SETOF refcursor AS
$BODY$
DECLARE
ref refcursor;
keepColumnsList text;
columnsList text;
valuesList text;
existQuery text;
keepQuery text;
BEGIN
IF keepcolumns IS NOT NULL AND array_length(keepColumns, 1) > 0 THEN
keepColumnsList := array_to_string(keepColumns, ', ');
ELSE
keepColumnsList := 'COUNT(*)';
END IF;
columnsList := (SELECT array_to_string(array_agg(name || ' = ' || value), ' OR ') FROM
(SELECT unnest(columns[1:1]) AS name, unnest(columns[2:2]) AS value) pair);
existQuery := 'SELECT ' || keepColumnsList || ' FROM ' || tableName || ' WHERE ' || columnsList;
RAISE NOTICE 'Exist query: %', existQuery;
OPEN ref FOR EXECUTE
existQuery;
RETURN next ref;
END;$BODY$
LANGUAGE plpgsql;
然后需要调用FETCH ALL IN
以获得结果。详细语法here或https://stackoverflow.com/a/12483222/630169。看来这是目前的唯一方法。希望将在PostgreSQL 11中使用PROCEDURES进行一些更改。