插入时的Postgres错误 - 错误:编码“UTF8”的无效字节序列:0x00

时间:2009-08-28 15:13:15

标签: postgresql

将数据从mysql插入postgres时出现以下错误。

我是否必须手动删除输入数据中的所有空字符? 有没有办法让postgres为我做这个?

ERROR: invalid byte sequence for encoding "UTF8": 0x00

7 个答案:

答案 0 :(得分:50)

PostgreSQL不支持在文本字段中存储NULL(\ 0x00)字符(这明显不同于完全支持的数据库NULL值。)

来源:http://www.postgresql.org/docs/9.1/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE

如果需要存储NULL字符,则必须使用bytea字段 - 该字段应存储您想要的任何内容,但不支持对其进行文本操作。

鉴于PostgreSQL在文本值中不支持它,没有好办法让它删除它。您可以将数据导入到bytea中,然后使用特殊函数将其转换为文本(在Perl或其他内容中,可能?),但在加载之前,在预处理中可能会更容易实现。

答案 1 :(得分:17)

只需正则输出空字节:

s/\x00//g;

答案 2 :(得分:10)

如果您使用的是Java,则可以在插入之前替换x00字符,如下所示:

private void OnAdd()
{
    foreach (Student s in StudentsToAdd)
    {
        Students.Add(s);
    }
    StudentsToAdd.Clear();
    StudentsToAdd.Add(new Student { FirstName = string.Empty, LastName = string.Empty });
}

private bool CanAdd()
{
    if (StudentsToAdd != null && StudentsToAdd.Count > 0)
    {
        return StudentsToAdd.All(x => !string.IsNullOrWhiteSpace(x.FirstName) && !string.IsNullOrWhiteSpace(x.LastName));
    }
    return false;
}

Csaba在以下文章中提供并解释了该解决方案:

This version

分别为:

  在Java中

,你的字符串中实际上可以有一个“0x0”字符   这是有效的unicode。所以它被转换为字符0x0 in   UTF8,由于服务器使用null,因此不接受   终止字符串...所以唯一的方法是确保你的字符串   不包含字符'\ u0000'。

答案 3 :(得分:1)

您可以先将数据插入blob字段,然后使用以下函数

复制到文本字段
CREATE OR REPLACE FUNCTION blob2text() RETURNS void AS $$
Declare
    ref record;
    i integer;
Begin
    FOR ref IN SELECT id, blob_field FROM table LOOP

          --  find 0x00 and replace with space    
      i := position(E'\\000'::bytea in ref.blob_field);
      WHILE i > 0 LOOP
        ref.bob_field := set_byte(ref.blob_field, i-1, 20);
        i := position(E'\\000'::bytea in ref.blobl_field);
      END LOOP

    UPDATE table SET field = encode(ref.blob_field, 'escape') WHERE id = ref.id;
    END LOOP;

End; $$ LANGUAGE plpgsql; 

-

SELECT blob2text();

答案 4 :(得分:0)

只有此正则表达式对我有用:

sed 's/\\0//g'

因此,在获取数据时,请执行以下操作:$ get_data | sed 's/\\0//g',它将在没有0x00的情况下输出数据

答案 5 :(得分:0)

如果您需要在文本字段中存储空字符,并且不想更改除文本之外的数据类型,那么您也可以按照我的解决方案进行操作:

在插入之前:

myValue = myValue.replaceAll("\u0000", "SomeVerySpecialText")

选择后:

myValue = myValue.replaceAll("SomeVerySpecialText","\u0000")

我已将“ null”用作我的SomeVerySpecialText,我确信我的值中根本没有任何“ null”字符串。

答案 6 :(得分:0)

使用COPY并使用包含NULL值(00)的转义字符串时,也可能发生这种错误:

"H\x00\x00\x00tj\xA8\x9E#D\x98+\xCA\xF0\xA7\xBBl\xC5\x19\xD7\x8D\xB6\x18\xEDJ\x1En"

如果您在未指定COPY的情况下使用format 'CSV',默认情况下将假设format 'text'。与反冲的相互作用不同,请参见text format

如果您使用的是COPYfile_fdw,请确保指定format 'CSV'以避免此类错误。