【发布时间】:2015-03-04 16:52:11
【问题描述】:
我创建了以下存储过程,它基本上接收一个表名和一个前缀。然后,该函数查找共享此前缀的所有列,并作为输出返回“选择”查询命令(“myoneliner”)。 如下:
CREATE OR REPLACE FUNCTION mytext (mytable text, myprefix text)
RETURNS text AS $myoneliner$
declare
myoneliner text;
BEGIN
SELECT 'SELECT ' || substr(cols,2,length(cols)-2) ||' FROM '||mytable
INTO myoneliner
FROM (
SELECT array(
SELECT DISTINCT quote_ident(column_name::text)
FROM information_schema.columns
WHERE table_name = mytable
AND column_name LIKE myprefix||'%'
order by quote_ident
)::text cols
) sub;
RETURN myoneliner;
END;
$myoneliner$ LANGUAGE plpgsql;
呼叫:
select mytext('dkj_p_k27ac','enri');
由于运行了这个存储过程和跟随它的“选择”,我在“数据输出”窗口中得到了以下输出(都在一个单元格中,名为“mytext text”):
'SELECT enrich_d_dkj_p_k27ac,enrich_lr_dkj_p_k27ac,enrich_r_dkj_p_k27ac
FROM dkj_p_k27ac'
我希望基本上能够将收到的输出命令行作为输出并执行它。换句话说,我希望能够并执行我的存储过程的输出。 我该怎么做?
我尝试了以下方法:
CREATE OR REPLACE FUNCTION mytext (mytable text, myprefix text)
RETURNS SETOF RECORD AS $$
declare
smalltext text;
myoneliner text;
BEGIN
SELECT 'SELECT ' || substr(cols,2,length(cols)-2) ||' FROM '||mytable
INTO myoneliner
FROM (
SELECT array(
SELECT DISTINCT quote_ident(column_name::text)
FROM information_schema.columns
WHERE table_name = mytable
AND column_name LIKE myprefix||'%'
order by quote_ident
)::text cols
) sub;
smalltext=lower(myoneliner);
raise notice '%','my additional text '||smalltext;
RETURN QUERY EXECUTE smalltext;
END;
$$ LANGUAGE plpgsql;
调用函数:
SELECT * from mytext('dkj_p_k27ac','enri');
但是我收到以下错误消息,请您告知我应该更改哪些内容才能执行?:
ERROR: a column definition list is required for functions returning "record"
LINE 26: SELECT * from mytext('dkj_p_k27ac','enri');
********** Error **********
ERROR: a column definition list is required for functions returning "record"
SQL state: 42601
Character: 728
【问题讨论】:
-
RETURN QUERY EXECUTE。但是,您的过程必须声明为RETURNING SETOF RECORD,然后调用者必须枚举调用中的列,这使得它没有用处。或者,您可以打开一个游标和RETURNS REFCURSOR,然后调用者可以从游标FETCH- 但在这种情况下,您不能将结果用作子查询等的一部分,只能将它们流式传输到客户端应用程序。 -
这看起来像是inner platform effect 的一个实例。我质疑设计。改用
hstore或json列怎么样? -
您需要以
select * from my_function(...)调用该过程 -
@Roy 这就是我要说的——你必须识别查询中的列,所以它不会给你带来太多好处。我说过“然后调用者将不得不枚举调用中的列”。您正在尝试做一些系统确实不擅长或专门设计的事情。
-
@Roy 有关信息,请参阅 the manual
setof record。
标签: postgresql stored-procedures plpgsql dynamic-sql