1

编辑:发布后,我发现Erwin Brandstetter 对类似问题的回答。听起来在 9.2+ 中我可以使用他列出的最后一个选项,但对于我的情况,其他选项听起来都不可行。然而,Jakub Kania 的评论和 Craig Ringer 重申的建议我在 psql 中使用 COPY 或 \copy 似乎解决了我的问题。

我的目标是将动态创建的查询执行到文本文件中的结果。

列名和列数未知;运行时生成的查询是“枢轴”查询,SELECT 列表中的列名取自存储在数据库中的值。

我的设想是能够从命令行运行:

$ psql -o "myfile.txt" -c "EXECUTE mySQLGeneratingFuntion(param1, param2)"

但是我发现除非我知道查询结果中的列数及其类型,否则我无法从 EXECUTEd 查询中获得结果。

create or replace function carrier_eligibility.createSQL() returns varchar AS
$$
begin
return 'SELECT * FROM carrier_eligibility.rule_result';
-- actual procedure writes a pivot query whose columns aren't known til run time
end
$$ language plpgsql

create or replace function carrier_eligibility.RunSQL() returns setof record AS
$$
begin 
return query EXECUTE carrier_eligibility.createSQL();
end
$$ language plpgsql

-- this works, but I want to be able to get the results into a text file without knowing
-- the number of columns 
select * from carrier_eligibility.RunSQL() AS (id int, uh varchar, duh varchar, what varchar)

不需要使用 psql。我只想将查询结果放入文本文件中,第一行中包含列名。

4

1 回答 1

0

你想要什么格式的文本文件?像csv这样的东西?

像这样的东西怎么样:

CREATE OR REPLACE FUNCTION sql_to_csv(in_sql text) returns setof text
SECURITY INVOKER -- CRITICAL DO NOT CHANGE THIS TO SECURITY DEFINER 
LANGUAGE PLPGSQL AS
$$
DECLARE t_row RECORD;
        t_out text;
BEGIN
  FOR t_row IN EXECUTE in_sql LOOP
     t_out := t_row::text;
     t_out := regexp_replace(regexp_replace(t_out, E'^\\(', ''), E'\\)$', '');
     return next t_out;
  END LOOP;
END; 
$$;

这应该创建没有标题的正确引用的 csv 字符串。嵌入的换行符可能是个问题,但您可以编写一个快速的 Perl 脚本来连接和写入数据或其他内容。

请注意,这假定元组结构(带括号的 csv)不会随着未来的版本而改变,但它目前至少应该在 8.4 到 9.2 中工作。

于 2013-05-16T05:14:00.573 回答