2013-01-02 77 views
2

我需要写从Postgres的文件到硬盘有后面紧跟一个斜杠反斜杠的字符串\/转义反斜线在PostgreSQL

代码类似这样没有工作:

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编码。

+0

听起来就像是'copy'命令不作为数据被正确地存储在数据库中的逃逸。虽然我不知道COPY命令的行为如何。 –

+0

[_可以在COPY数据中使用折叠字符(\\)来引用可能作为行或列分隔符使用的数据字符。特别是,如果以下字符作为列值的一部分显示,则必须在前面加上反斜杠:反斜杠本身,换行符,回车符,以及当前的分隔字符._](http://www.postgresql.org/docs /current/static/sql-copy.html) –

回答

2

问题是COPY不是用来写出纯文本文件。它旨在写出可由COPY读回的文件。而它使用的半内部编码做了一些反斜杠转义。

对于您想要做的事情,您需要编写一些自定义代码。要么使用普通的客户端库来读取查询结果并将它们写入文件,要么使用PL/Perl或PL/Python之类的东西。

+0

你可能是对的,这是我不想听到的答案。除非有其他想法,否则我可能需要长时间解决这个问题......我将代码中的反斜杠部分放入一个单独的shell脚本中,并且我将让postgres生成一个调用并将一个变量传递给该脚本。这似乎是目前最干净的方法。 [我希望有一个用于编写纯文本文件的Postgres模块]谢谢。 – Paulb

0

的\ excaping如果串文字是为E前缀时,才能识别,否则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的为认领headerline应consdered功能

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

谢谢。至少在我的配置中,我试过这个代码,没有运气。它产生// foo foo foo/bar/bar。 – Paulb

+0

但是你希望* *反斜杠和斜杠在字符串中?什么是原始字符串?(我认为values()是用于演示的目的) – wildplasser

+0

谢谢。我会看看。我一直试图用你的代码建议..结果从来没有奏效,有时他们是意想不到的。我认为彼得是正确的。复制是为了自己的目的在做内部事情。我将探索CSV的想法。 – Paulb