在postgres(plpgsql)中,如何创建一个在变量table_name上返回select *的函数?

时间:2011-03-28 14:11:26

标签: postgresql plpgsql

基本上,至少为了概念证明,我想要一个我可以运行的函数: SELECT res('table_name');这将给我SELECT * FROM table_name;的结果。 我遇到的问题是架构......在我所拥有的函数的声明中:

创建或替换功能res(table_name TEXT)返回设置此THEPISEPEPROBLEM

问题是我不知道如何声明我的返回,因为它要我指定一个表或一个模式,在实际运行该函数之前我不会这样做。

有什么想法吗?

3 个答案:

答案 0 :(得分:7)

您可以执行此操作,但如前所述,您必须在SELECT查询中添加列定义列表。

CREATE OR REPLACE FUNCTION res(table_name TEXT)  RETURNS SETOF record AS $$
BEGIN
  RETURN QUERY EXECUTE 'SELECT * FROM ' || table_name;
END;
$$ LANGUAGE plpgsql;


SELECT * FROM res('sometable') sometable (col1 INTEGER, col2 INTEGER, col3 SMALLINT, col4 TEXT);

答案 1 :(得分:4)

为什么出于任何实际目的,你只想传入表并从中选择*?好玩的可能吗?

如果没有定义像jack和rudi show这样的已知输出,你就无法做到。或者像depesz这样使用输出参数http://www.depesz.com/index.php/2008/05/03/waiting-for-84-return-query-execute-and-cursor_tuple_fraction/

围绕墙壁方法的一些方法是在循环中发出引发通知并一次打印出一行结果集。或者,您可以创建一个名为get_rows_TABLENAME的函数,该函数具有要返回的每个表的定义。只需使用代码生成程序创建。但是再次不确定从一张桌子做一个选择*有多大的价值,特别是没有限制,不仅仅是为了好玩或让DBA的热血沸腾。

现在,在SQL Server中,您可以让存储过程返回动态结果集。这既是一种祝福又是一种诅咒,因为你无法确定在没有查找定义的情况下会发生什么。对我来说,我看看PostgreSQL的实现是更合理的方式。

答案 2 :(得分:2)

即使你设法做到这一点(如果你有8.4或以上的话,请参阅rudi-moore的答案),你必须在select明确地扩展类型 - 例如:

SELECT res('table_name') as foo(id int,...)