3

我正在尝试在 postgres 9.3 上使用 sql 在函数中调用函数。

这个问题与我的另一篇文章有​​关

我写了下面的函数。到目前为止,我未能合并任何类型的保存输出 (COPY) 语句,因此我试图通过创建嵌套函数打印输出函数来解决此问题。

CREATE FUNCTION retrieve_info(TEXT, TEXT) RETURNS SETOF   
retrieve_info_tbl AS $$
 SELECT tblA.id, tblA.method, tblA.species, tblA.location
 FROM tblA
 WHERE method=$1 AND species=$2
 GROUP BY id, method, species
 ORDER BY location
$$ LANGUAGE 'sql';

上述功能有效。

尝试创建嵌套函数。

CREATE FUNCTION print_out(TEXT, TEXT) RETURNS void AS $$
 COPY (SELECT * FROM retrieve_info($1, $2)) TO 'myfilepath/test.csv'    
 WITH CSV HEADER;
$$ LANGUAGE 'sql';

调用嵌套函数。

SELECT * FROM print_out('mtd1','sp1');

输出

以上给出了这个ERROR: column "$1" does not exist SQL state: 42P02 Context: SQL function "print_out" statement 1。但是,当用 'mtd1','sp1' 替换 print_out() 中的 arg1、arg2 时,正确的输出会打印到 test.csv(如下所示)

id | method | ind | location
----------------------------
1a | mtd1   | sp3 | locA
1d | mtd1   | sp3 | locB

如何让retrieve_info() 的arg1、arg2 在print_out() 中正确调用arg1、arg2?

我完全被困住了。不胜感激任何指针,谢谢

4

2 回答 2

4

COPY有点奇怪,因为它有点将其query参数视为字符串,即使它没有写为字符串。结果是query

SELECT * FROM retrieve_info($1, $2)

不在函数的上下文中执行,而是在 COPY 本身的上下文中执行。即使你说:

copy (select * from t) ...

它被视为更像你写的:

copy 'select * from t' ...

所以到执行查询时,函数参数不再具有任何意义,queryCOPY 的参数可能看起来像其他语言中的闭包,但实际上并非如此,它更像是传递给的字符串eval.

您可以通过使用通常的最后手段的 Kludge 来解决这种奇怪问题:动态 SQL。如果您编写函数以使用字符串整理和执行,您应该会得到更好的结果:

create or replace function print_out(text, text) returns void as $$
begin
    execute 'copy ('
         || 'select * from retrieve_info'
         ||     '(' || quote_literal($1) || ',' || quote_literal($2) || ')'
         || ') to ''myfilepath/test.csv'' with csv header;';
end;
$$ language plpgsql;
于 2013-11-14T06:05:24.077 回答
0

是故意引用x的吗?y

COPY (SELECT * FROM retrieve_info('x','y')) TO 'myfilepath/test.csv'

您没有发送 to 的andx参数y,而是发送字符串and 。假设您没有带有的记录,那么您没有得到任何结果也就不足为奇了。print_outretrieve_info'x''y'method='x' AND species='y'

试试这个:

COPY (SELECT * FROM retrieve_info(x,y)) TO 'myfilepath/test.csv'
于 2013-11-12T02:06:52.177 回答