在psql的\copy中进行变量替换

9
在PSQL控制台中,是否可以导出带有当前日期的文件名?导出的文件名应该像这样table_20140710.csv。是否可以动态实现这一点?-日期格式可能与上述不同,但并不是很重要。
以下是我所理解的示例:
\set curdate current_date
\copy (SELECT * FROM table) To 'C:/users/user/desktop/table_ ' || :curdate  || '.csv' WITH DELIMITER AS ';' CSV HEADER
3个回答

11

\copy元命令不扩展变量的异常已经(同时)文档化

与大多数其他元命令不同,整行剩余部分始终被视为 \copy 的参数,参数中不执行变量插值或反引号扩展。

要解决此问题,您可以构建、存储并执行多个步骤的命令(类似于 Clodoaldo Neto 给出的解决方案):

\set filename 'my fancy dynamic name'
\set command '\\copy (SELECT * FROM generate_series(1, 5)) to ' :'filename'
:command

在此,您需要在嵌入的元命令中双倍(转义)任何\'。请记住,\set将所有后续参数连接到第二个参数,因此请引用参数之间的空格。您可以使用\echo :command显示执行前的命令(:command)。

作为本地\set命令的替代方案,您还可以使用SQL在服务器端构建命令(最佳方法取决于动态内容的来源):

SELECT '\copy (SELECT * FROM generate_series(1, 5)) to ''' || :'filename' || '''' AS command \gset

4
动态构建 \copy 命令并将其存储在文件中。然后使用 \i 执行它。
首先设置仅输出元组。
\t

将输出设置到文件中

\o 'C:/users/user/desktop/copy_command.txt'

构建 \copy 命令。
select format(
    $$\copy (select * from the_table) To 'C:/users/user/desktop/table_%s.csv' WITH DELIMITER AS ';' CSV HEADER$$
    , current_date
);

将输出恢复为stdout

\o

执行从文件生成的命令

\i 'C:/users/user/desktop/copy_command.txt'

0

postgresql手册中建议的使用psql的\copy命令的替代方法是使用服务器端copy命令将输出导出到stdout。

获取与\copy...to相同结果的另一种方法是使用SQL COPY ... TO STDOUT命令,并用\g文件名或\g |程序终止它。与\copy不同,此方法允许命令跨越多行;还可以使用变量插值和反引号扩展。

对于给定的示例,它将如下所示:

COPY (SELECT * FROM table) TO STDOUT WITH DELIMITER AS ';' CSV HEADER \g 'table_':curdate'.csv'

或者,可以说,将内容友好地分散在多行中更容易阅读:
COPY (SELECT * FROM table) TO STDOUT 
WITH DELIMITER AS ';' CSV HEADER 
\g 'table_':curdate'.csv'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接