【问题标题】:22021: invalid byte sequence for encoding "UTF8": 0x0022021:用于编码“UTF8”的无效字节序列:0x00
【发布时间】:2019-06-08 15:14:33
【问题描述】:

我正在从 C# 批量导入到 PostgreSQL,其中一条记录给了我这个错误:

22021:编码“UTF8”的字节序列无效:0x00

我用谷歌搜索了它,一般建议是这指的是一个空字段,但在我的例子中,情况并非如此。我追踪了导致错误的字符串,它是这样的:

解决以下问题:令 $A$ 为 Banach 代数,令 $\sum:\0\rightarrow I\rightarrow\mathfrak A\overset\pi\to\longrightarrow A\rightarrow 0$ 为 $ 的扩展A$,其中 $\mathfrak A$ 是 Banach 代数,$I$ 是 $\mathfrak A$ 中的封闭理想。

我正在从一个 XML 文件中读取它,并在文件流中定义了 UTF-8。

我的反序列化 C# 类上的转义字符串是:

"Addresses the following: Let $A$ be a Banach algebra, and let $\\sum\\:\\0\\rightarrow I\\rightarrow\\mathfrak A\\overset\\pi\\to\\longrightarrow A\\rightarrow 0$ be an extension of $A$, where $\\mathfrak A$ is a Banach algebra and $I$ is a closed ideal in $\\mathfrak A$."

显然字符串有问题。我猜应该存在某种数学符号,但这究竟是什么破坏了导入并使 PostgreSQL 报告它是一个空字段?应该以什么格式读取?

如果我手动覆盖此字段,则导入有效,因此此字符串 100% 存在问题。

【问题讨论】:

  • Afaik,PostgreSQL 不允许字符串中有空字节(NUL 字符)。您的字符串在某处包含 NUL 字符 ('\0')。我建议您将字符串转换为 C# 中的 char[] 数组,并检查该数组是否以及在哪个位置具有值为零的元素。 (另一方面,我猜可以将字符串中的"\0" 替换为空字符串"",但这样做是否真的可以,只有您可以决定)
  • 啊,你是对的,我明白了。谢谢你,你给了我寻找解决方案的工具
  • 我运行了一个快速脚本,C# 没有将任何字符值设置为零。更有可能当 Postgres 接收到字符串时,它正在转义字符串中存在的 \0。请参阅下面的答案。

标签: c# postgresql


【解决方案1】:

由于它是批量导入,我假设您正在创建一个文件或某种大字符串以发送到 Postgres?在这种情况下,字符串可能启用了转义字符,而不是通过准备好的语句执行此操作。因此,Postgres 可能将字符串中的 \0 转义并解释为 0x00。

来自文档:https://www.postgresql.org/docs/8.3/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS

PostgreSQL 也接受“转义”字符串常量,这是对 SQL 标准的扩展。转义字符串常量是通过在开始单引号之前写字母 E(大写或小写)来指定的,例如E'foo'。 (当跨行继续转义字符串常量时,仅在第一个开始引号之前写 E。)在转义字符串中,反斜杠字符 () 开始类似 C 的反斜杠转义序列,其中反斜杠和后续字符的组合(s ) 表示一个特殊的字节值。 \b 是退格,\f 是换页,\n 是换行符,\r 是回车符,\t 是制表符。还支持 \digits,其中 digits 表示八进制字节值,以及 \xhexdigits,其中 hexdigits 表示十六进制字节值。 (您有责任确保您创建的字节序列是服务器字符集编码中的有效字符。)反斜杠后面的任何其他字符都按字面意思表示。因此,要包含反斜杠字符,请编写两个反斜杠 (\)。此外,除了普通的 '' 之外,还可以通过写 \' 将单引号包含在转义字符串中。

因此,如果您的批量语句在字符串前面加上 E,例如 E'hello',请不要这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-28
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2014-08-02
    • 1970-01-01
    相关资源
    最近更新 更多