在Postgresql中转义反斜杠

时间:2013-01-02 15:24:44

标签: postgresql escaping

我需要从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。

2 个答案:

答案 0 :(得分:2)

问题是COPY不打算写出纯文本文件。它旨在写出COPY可以回读的文件。它使用的半内部编码会产生一些反斜杠转义。

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

答案 1 :(得分: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';

更新:一个丑陋的黑客是使用.csv格式,仍然使用\ t作为分隔符。 作为shebang标题的#!/ bin / sh应该是一个特征

       -- 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'
        ;