在动态COPY语句中使用函数变量

sim*_*mar 1 postgresql plpgsql

根据PostgreSQL的文档,可以直接从查询中将数据复制到csv文件,而无需使用中间表.我很好奇如何做到这一点.

CREATE OR REPLACE FUNCTION m_tbl(my_var integer)
    RETURNS void AS
$BODY$
DECLARE
BEGIN

   COPY (
       select my_var
   )
   TO 'c:/temp/out.csv';

END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:没有这样的列'my_var'.

Cra*_*ger 8

是的,可以COPY从任何查询中,无论它是否引用表.

但是,COPY是一个非计划性的声明,一个实用程序声明.它不支持查询参数 - 查询参数是PL/PgSQL如何实现将变量插入语句.

所以你不能使用PL/PgSQL变量COPY.

您必须使用动态SQL EXECUTE.有关示例,请参阅Pl/PgSQL文档.Stack Overflow和https://dba.stackexchange.com/上有很多例子.

就像是:

EXECUTE format('
   COPY (
       select %L
   )
   TO ''c:/temp/out.csv'';
', my_var);
Run Code Online (Sandbox Code Playgroud)

如果您希望文件路径是动态的,则同样适用- 您将使用:

EXECUTE format('
   COPY (
       select %L
   )
   TO %L;
', my_var, 'file_name.csv');
Run Code Online (Sandbox Code Playgroud)

它也适用于动态列名称,但您可以使用%I(对于标识符,"my_name"而不是%L像文字一样)'my_value'.有关详细信息%I,并%L,请参阅该文档format.