设置:Postgresql Server 9.3 - 操作系统:CentOS 6.6
尝试使用COPY命令将2.5亿条记录批量插入Postgresql 9.3服务器。数据采用分隔格式,使用管道' |'作为分隔符。
我复制到的表中几乎所有列都是TEXT数据类型。不幸的是,在2.5亿条记录中,大约有200万条记录具有合法的文本值,其中包含" \ 0"在文中。
示例条目:
245150963 | DATASOURCE | 736778 | XYZNR-1B5.1 | 10-DEC-1984 00:00:00 ||| XYZNR-1B5.1 \ 1984-12-10 \ 0.5 \ 1 \ ASDF1 | pH |物理|水| XYZNR |口
如您所见,第8列的值为0。
XYZNR-1B5.1 \ 1984年12月10日\ 0.5 \ 1 \ ASDF1
无论我如何逃避这一点,COPY命令都会将此\ 0转换为实际的" \ x0"或者COPY命令失败,出现" ERROR:编码的无效字节序列" UTF8":0x00"。
我尝试用" sed -i"替换\ 0用:
\\0
\\\0
'\0'
\'\'0
\\\\\0
......以及其他许多我无法记住的事情,但没有一个能够奏效。
这些类型的字符串的正确转义是什么?
谢谢!
答案 0 :(得分:3)
关于COPY的Per Postgres文档:
反斜杠字符()可以在COPY数据中用于引用数据 否则可能被视为行或列分隔符的字符。 特别是,以下字符必须以开头 反斜杠如果它们作为列值的一部分出现:反斜杠本身, 换行符,回车符和当前分隔符。
尝试将字段中该路径中的所有反斜杠字符转换为\\,而不仅仅是\ 0。
FYI \ b也是反斜杠的缩写。
所以这些都应该有效:
XYZNR-1B5.1 \ b1984-12-10 \ B0.5 \ B1 \ bASDF1
XYZNR-1B5.1 \\ 1984年12月10日\\ 0.5 \\ 1 \\ ASDF1
答案 1 :(得分:1)
你需要的那个是你没有给出的一个例子:
sed -e 's/\\/\\\\/g'
您希望所有\
出现,而不仅仅是\0
。
从文件和postgres的角度来看,我们试图将\
转换为\\
。
在sed
中,\
是我们需要自行转义的特殊字符,因此\
变为\\
,\\
变为\\\\
因此,上面的表达。
答案 2 :(得分:0)
您确认您的sed
命令实际上是在给您\\0
吗?