将数据从mysql插入postgres时出现以下错误。
我是否必须从输入数据中手动删除所有空字符?有没有办法让postgres为我做这件事?
ERROR: invalid byte sequence for encoding "UTF8": 0x00
Answers:
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或其他功能中)将其转换为文本,但是在加载之前进行预处理可能会更容易。
只是正则表达式输出空字节:
s/\x00//g;
replaceAll("s/\x00//g","")
导致将它们替换为其他null吗?
如果使用的是Java,则只需在插入之前替换x00字符,如下所示:
myValue.replaceAll("\u0000", "")
Csaba在以下帖子中提供了解决方案并进行了解释:
https://www.postgresql.org/message-id/1171970019.3101.328.camel%40coppola.muc.ecircle.de
分别:
在Java中,您的字符串中实际上可以有一个“ 0x0”字符,这是有效的unicode。因此,它被转换为UTF8中的字符0x0,而该字符又被接受,因为服务器使用以空值终止的字符串...因此,唯一的方法是确保字符串不包含字符'\ u0000'。
您可以先将数据插入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();
如果您需要在文本字段中存储空字符,并且不想更改除文本之外的数据类型,那么您也可以按照我的解决方案进行操作:
插入之前:
myValue = myValue.replaceAll("\u0000", "SomeVerySpecialText")
选择后:
myValue = myValue.replaceAll("SomeVerySpecialText","\u0000")
我已经将“ null”用作我的SomeVerySpecialText,我确信我的值中根本没有任何“ null”字符串。
CREATE TABLE store_bytes ( key INTEGER NOT NULL, data bytea NOT NULL );