我正在生成一个 SQL 命令列表来导出一些我最终使用 psql -f 运行的数据。查询都获得相同的数据子集,所以我想我会考虑资格,并将符合条件的用户 ID 列表放入临时表中,如下所示
create temporary table tmp_export_users as (select id from users where ...)
Run Code Online (Sandbox Code Playgroud)
然后在我的 \copy 命令中参考
\copy (select ... from table where user_id in (select id from tmp_export_users)) TO 'filename.csv' WITH CSV HEADER
Run Code Online (Sandbox Code Playgroud)
这些都在同一个文件中,每行一个,并运行它们 -f 我得到复制命令看不到临时表的错误,所以我猜客户端复制命令实际上不能使用相同的 postgres会话为 psql。
那是对的吗?有没有办法改变这种行为?
Erw*_*ter 18
\copy
可以使用临时表。
首先,我在命令行中使用9.0版测试并确认了这一点。
然后我\copy
使用多个临时表使用SQL 和 psql meta 命令创建了一个文件。这对我也有用。
CREATE TEMP TABLE tmp as SELECT * FROM tbl;
\copy (SELECT * FROM tmp JOIN tbl USING (id)) TO '/var/lib/postgres/test1.csv';
Run Code Online (Sandbox Code Playgroud)
称呼:
psql -p5432 mydb -f test.sql
Run Code Online (Sandbox Code Playgroud)
请注意终止分号,它在文件末尾是可选的(隐式终止),但在任何其他 SQL 语句之后以及如果在 psql 中交互式执行时也需要在最后一个语句之后。
通常情况下,psql元命令不能与SQL是混合在同一行中每执行的文件psql -f
。我引用了psql的手册:
参数解析在行尾停止,或者在找到另一个未加引号的反斜杠时停止。未加引号的反斜杠被视为新元命令的开头。特殊序列
\\
(两个反斜杠)标记参数的结束并继续解析 SQL 命令(如果有)。这样 SQL 和 psql 命令可以在一行中自由混合。但无论如何,元命令的参数不能超出行尾。
但是,在 之后 适用不同的规则\copy
。本质上,psql 在\copy
查看后自动切换回 SQL 模式:
但是你写了所有命令都在单独的行上。所以这不能解释你的情况。
除此之外,您是否考虑过使用COPY
(SQL 命令)而不是\copy
(psql 元命令)?
当然,在这种情况下,目标文件必须是服务器本地的,而不是客户端的。并且适用不同的文件权限。手册:
COPY
命令中命名的文件由服务器直接读取或写入,而不是由客户端应用程序读取或写入。因此,它们必须驻留在数据库服务器计算机上或可由其访问,而不是客户端。它们必须可由 PostgreSQL 用户(服务器运行的用户 ID)而不是客户端访问和读取或写入。