将数据从mysql插入postgres时出现以下错误。
我是否必须手动删除输入数据中的所有空字符? 有没有办法让postgres为我做这个?
ERROR: invalid byte sequence for encoding "UTF8": 0x00
答案 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在以下文章中提供并解释了该解决方案:
分别为:
在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。
如果您使用的是COPY
或file_fdw
,请确保指定format 'CSV'
以避免此类错误。