我需要一个简单的函数来返回动态的列集。我在SO上找到了几个例子,最后得到了以下结论:
CREATE or replace FUNCTION getColumn(_column1 text, _column2 text, _column3 text, _table text)
RETURNS TABLE(cmf1 text, cmf2 text, cmf3 text) AS $$
BEGIN
RETURN QUERY EXECUTE
'SELECT '
|| quote_ident(_column1)::text || ' as cmf1,'
|| quote_ident(_column2)::text || ' as cmf2,'
|| quote_ident(_column3)::text || ' as cmf3'
' FROM '
|| quote_ident(_table);
END;
$$ LANGUAGE plpgsql;
我需要这个函数只能用于varchar / text列,所以我创建了这个测试表:
create table test20130205 (
a text,
b text,
c varchar,
d text)
;
最后,我可以进行一些测试:
select * from getColumn('a','b','d','test20130205');
-- ok
select * from getColumn('a','b','c','test20130205');
-- error
ERROR: structure of query does not match function result type
DETAIL: Returned type character varying does not match expected type text in column 3.
CONTEXT: PL/pgSQL function getcolumn(text,text,text,text) line 3 at RETURN QUERY
似乎在演员之前检查了列c(varchar)的类型 - 这看起来很奇怪,但我想我错过了一些东西。
如何修复我的功能?
(PostgreSQL 9.1)
答案 0 :(得分:6)
在当前函数中,转换为文本的转换不适用于输出列值,它们适用于它们的名称(quote_ident
的结果)。
应该在查询本身内移动强制转换:
CREATE or replace FUNCTION getColumn(_column1 text, _column2 text, _column3 text, _table text)
RETURNS TABLE(cmf1 text, cmf2 text, cmf3 text) AS $$
BEGIN
RETURN QUERY EXECUTE
'SELECT '
|| quote_ident(_column1) || '::text as cmf1,'
|| quote_ident(_column2) || '::text as cmf2,'
|| quote_ident(_column3) || '::text as cmf3'
' FROM '
|| quote_ident(_table);
END;
$$ LANGUAGE plpgsql;