2

我需要从 postgres 将文件写入磁盘,该文件具有反斜杠字符串,后跟正斜杠\/

与此类似的代码不起作用:

drop table if exists test;
create temporary table test (linetext text);
insert into test values ('\/\/foo foo foo\/bar\/bar');
copy (select linetext from test) to '/filepath/postproductionscript.sh';

上面的代码产生\\/\\/foo foo foo\\/bar\\/bar......它插入了一个额外的反斜杠。

当您查看临时表时,字符串被正确地视为\/\/,所以我不确定文本在何处或何时更改为\\/\\/

我尝试\在字符串之前将 E 的 , 变体和 quote_literal() 加倍,但没有运气。

我注意到这里找到了解决方案Postgres Manual

运行 Postgres 9.2,编码为 UTF-8。

4

2 回答 2

2

问题在于它COPY不打算写出纯文本文件。它旨在写出可由COPY. 它使用的半内部编码会进行一些反斜杠转义。

对于您想要做的事情,您需要编写一些自定义代码。使用普通的客户端库来读取查询结果并将它们写入文件,或者,如果您想在服务器中执行此操作,请使用 PL/Perl 或 PL/Python 之类的东西。

于 2013-01-02T15:39:48.310 回答
0

仅当 stringliteral 以 E 为前缀时才识别 \ excaping,否则遵循 standard_conforming_strings 设置(或类似设置)(ANSI-SQL 具有不同的字符串转义方式,可能源于 COBOL;-)。

drop table if exists test;
create temporary table test (linetext text);
insert into test values ( E'\/\/foo foo foo\/bar\/bar');
copy (select linetext from test) to '/tmp/postproductionscript.sh';

UPATE:一个丑陋的黑客是使用 .csv 格式并仍然使用 \t 作为分隔符。#!/bin/sh 作为 shebang 标题行应该被视为一个功能

       -- without a header line
drop table if exists test;
create temporary table test (linetext text);
insert into test values ( '\/\/foo foo foo\/bar\/bar');
copy (select linetext AS "#linetext" from test) to '/tmp/postproductionscript_c.sh'
        WITH CSV
        DELIMITER E'\t'
        ;
        -- with a shebang header line
drop table if exists test;
create temporary table test (linetext text);
insert into test values ( '\/\/foo foo foo\/bar\/bar');
copy (select linetext AS "#/bin/sh" from test) to '/tmp/postproductionscript_h.sh'
        WITH CSV
        HEADER
        DELIMITER E'\t'
        ;
于 2013-01-02T16:14:06.197 回答