【问题标题】:Postgresql COPY with text value containing \0 (backslash 0)文本值包含 \0(反斜杠 0)的 Postgresql COPY
【发布时间】:2016-11-11 07:52:11
【问题描述】:

设置:Postgresql 服务器 9.3 - 操作系统:CentOS 6.6

尝试使用 COPY 命令将 2.5 亿条记录批量插入 Postgresql 9.3 服务器。数据采用管道“|”分隔格式作为分隔符。

我要复制到的表中几乎所有列都是 TEXT 数据类型。不幸的是,在 2.5 亿条记录中,大约有 200 万条具有合法的文本值,文本中带有“\0”。

示例条目:

245150963|数据源|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: invalid byte sequence for encoding "UTF8": 0x00"。

我尝试将 \0 替换为“sed -i”:

\\0
\\\0
'\0'
\'\'0
\\\\\0

...还有很多其他我不记得了,但它们都不起作用。

这些类型的字符串的正确转义是什么?

谢谢!

【问题讨论】:

  • 您是否尝试在 COPY TO 上提供 WITH NULL 参数?
  • 我也有同样的问题,你找到解决办法了吗?

标签: postgresql text escaping psql backslash


【解决方案1】:

COPY 上的每个 Postgres 文档:

可以在COPY数据中使用反斜杠字符()来引用数据 否则可能被视为行或列分隔符的字符。 特别是,以下字符前面必须有一个 反斜杠,如果它们作为列值的一部分出现:反斜杠本身, 换行符、回车符和当前分隔符。

尝试将字段中该路径中的所有反斜杠字符转换为 \\,而不仅仅是 \0。

仅供参考 \b 也是反斜杠的简写。

所以这些都应该工作:

XYZNR-1B5.1\b1984-12-10\b0.5\b1\bASDF1
XYZNR-1B5.1\\1984-12-10\\0.5\\1\\ASDF1

【讨论】:

  • 我以前从未听说过\b,所以我立即尝试了。不幸的是,虽然 COPY 命令成功完成了插入的数据,但最终结果如下:XYZNR-EE2.2\x081984-12-13\x080\x081\x08S-ASDF1。就像我上面所说的那样,我尝试了 \\ 做事的方式,结果也和 \b 一样。不过感谢您的建议!
【解决方案2】:

你需要的是一个你没有给出的例子:

sed -e 's/\\/\\\\/g'

您希望所有出现的\ 都使用此功能,而不仅仅是\0

从文件和 postgres 的角度来看,正在尝试将 \ 转换为 \\

sed中,\是一个特殊的字符,我们需要自我转义,所以\变成\\\\变成\\\\,所以上面的表达式。

【讨论】:

    【解决方案3】:

    您是否确认您的sed 命令实际上是给您\\0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多