【问题标题】:Postgres PL/pgSQL Function results to file, with filename as argumentPostgres PL/pgSQL 函数结果到文件,文件名作为参数
【发布时间】:2014-05-07 16:02:22
【问题描述】:

我正在将一些客户端的东西迁移到服务器中,并希望将其放入一个函数中。

我需要将查询结果保存到 CSV 文件中。但是,我想将结果文件的文件名/位置作为函数的参数传递。

所以,这是我想做的一个简单示例:

CREATE FUNCTION send_email_results(filename1 varchar) RETURNS void AS $$
DECLARE
BEGIN
    COPY(SELECT * FROM mytable) TO filename1 WITH CSV;
END;
$$ LANGUAGE plpgsql;

不过,Postgres 对此有所抱怨,因为它正在将 filename1 参数转换为“$1”,但它不知道该怎么做。

如果需要,我可以对路径进行硬编码,但能够将其作为参数传递肯定会很方便。

谁有线索?

【问题讨论】:

  • 公平地说,我想在函数中执行此操作的原因是我需要导出到函数中的多个文件。所以想象一下需要传递 2 或 3 个不同的文件名作为参数,并在该函数中导出一些不同的查询。如果我不需要导出多个查询,那么我可以简单地输出输出。
  • 在函数中使用 EXECUTE 'your query'。
  • COPY with dynamic file name 的可能重复项

标签: sql postgresql csv copy plpgsql


【解决方案1】:

我刚碰到这个。事实证明,当使用复制命令时,您不能使用参数化参数(至少使用 python 作为存储过程语言的情况是这样)。因此,您必须构建不带参数的命令,例如:

CREATE FUNCTION send_email_results(filename1 varchar) RETURNS void AS $$
DECLARE
BEGIN
    execute 'copy (select * frommytable) to ' || filename1 || ' with csv;';
END;
$$ LANGUAGE plpgsql;

您可能必须使用引用功能使其更具可读性。我不知道,我没有使用plpgsql作为postgres函数语言,所以语法可能是错误的。

execute 'copy (select * frommytable) to ' || quote_literal(filename1) || ' with csv;'

【讨论】:

  • 就是这样。效果很好。最后一点是我仍然必须在文件名周围添加转义的单引号,所以它最终看起来像TO ''' || filename1 || ''' WITH CSV;';
  • @jasonmclose:如果您使用简单的字符串连接,这很容易受到 SQL 注入的影响。而是使用带有quote_literal()format() with %L 的第二种形式。
  • 现在在 postgres v.10 中,情况仍然如此。谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
  • 2020-06-25
  • 2012-09-16
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
相关资源
最近更新 更多