0

我很想我的 PL/pgSQL 函数中利用 PostgreSQL 的 SQL 输出格式,但我开始觉得我必须放弃这个想法。

我有我的 PL/pgSQL 函数query_result

CREATE OR REPLACE FUNCTION query_result(
    this_query text
) RETURNS SETOF record AS  
$$
    BEGIN
      RETURN QUERY EXECUTE this_query;
    END;
$$ LANGUAGE plpgsql;

..愉快地从输入文本查询中返回SETOF记录,我可以将其用于动态查询的 SQL 脚本:

mydb=# SELECT * FROM query_result('SELECT ' || :MYVAR || ' FROM Alice') AS t (id int);
 id 
----
  1
  2
  3

所以我希望找到一种方法,从PL/pgSQL函数内部提供同样格式良好的输出,但不支持类型,并且没有从记录到文本的预定义魔法转换(我知道我可以创建自己的.. )RAISESETOFSETOFCAST

如果我创建一个虚拟print_result函数:

CREATE OR REPLACE FUNCTION print_result(
    this_query text
) RETURNS void AS 
$$
    BEGIN
      SELECT query_result(this_query);                                                                                                                                   
    END;
$$ LANGUAGE plpgsql;

..我无法打印格式化的输出:

mydb=# SELECT print_result('SELECT ' || :MYVAR || ' FROM Alice');
ERROR:  set-valued function called in context that cannot accept a set
...

感谢您的任何建议(最好与 PostgreSQL 8.4 一起使用)。

4

1 回答 1

1

好的,要对您的结果集做任何事情,您print_result必须遍历它。看起来像这样 -

这里result_record定义为record变量。为了解释起见,我们还假设您有一个formatted_results变量,该变量定义为text并默认为空白字符串以保存格式化的结果。

FOR result_record IN SELECT * FROM query_result(this_query) AS t (id int) LOOP
    -- With all this, you can do something like this
    formatted_results := formatted_results ||','|| result_record.id;
END LOOP;

RETURN formatted_results;

因此,如果您更改print_results为返回文本,按照我的描述声明变量并添加它,您的函数将返回一个逗号分隔的所有结果列表(最后有一个额外的逗号,我相信您可以利用 PostgreSQL 的字符串函数来修剪它)。我不确定这是否正是您想要的,但这应该让您对如何操作结果集有一个很好的了解。您可以在此处获得有关控制结构的更多信息,这应该可以让您做几乎任何您想做的事情。

编辑回答真正的问题:

将数据元组格式化为可读文本的能力是 psql 客户端的功能,而不是 PostgreSQL 服务器的功能。要使此功能在服务器中可用,需要从 psql 实用程序中提取相关代码或模块,并将它们重新编译为数据库函数。这似乎是可能的(也可能有人已经这样做了),但我对这个过程还不够熟悉,无法很好地描述如何做到这一点。最有可能的是,将查询结果格式化为文本的最佳解决方案是利用 PostgreSQL 的字符串格式化函数来实现应用程序所需的功能。

于 2013-06-21T15:19:53.700 回答