Ошибка Postgres при вставке - ОШИБКА: неверная последовательность байтов для кодировки "UTF8": 0x00 - PullRequest
59 голосов
/ 28 августа 2009

Я получаю следующую ошибку при вставке данных из mysql в postgres.

Нужно ли вручную удалять все нулевые символы из моих входных данных? Есть ли способ получить postgres, чтобы сделать это для меня?

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

Ответы [ 6 ]

50 голосов
/ 28 августа 2009

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 или что-то в этом роде?), Но, вероятно, будет проще сделать это при предварительной обработке перед загрузкой.

17 голосов
/ 08 января 2013

Просто выведите нулевые байты:

s/\x00//g;
11 голосов
/ 22 августа 2017

Если вы используете Java, вы можете просто заменить символы x00 перед вставкой следующим образом:

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

Решение было предоставлено и объяснено Csaba в следующем посте:

https://www.postgresql.org/message-id/1171970019.3101.328.camel%40coppola.muc.ecircle.de

Соответственно:

в Java вы можете иметь символ "0x0" в вашей строке, и это действительный юникод. Так что это переводится на символ 0x0 в UTF8, который в свою очередь не принят, потому что сервер использует нуль завершенные строки ... так что единственный способ убедиться, что ваши строки не содержит символ '\ u0000'.

1 голос
/ 13 октября 2009

Вы можете сначала вставить данные в поле большого двоичного объекта, а затем скопировать в текстовое поле с помощью следующей функции

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();
0 голосов
/ 26 ноября 2018

Если вам нужно хранить нулевые символы в текстовых полях и не хотите менять тип данных, кроме текста, вы также можете следовать моему решению:

Перед вставкой:

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

После выбора:

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

Я использовал "null" в качестве SomeVerySpecialText, и я уверен, что в моих значениях не будет никакой "нулевой" строки.

0 голосов
/ 05 октября 2018

Только у меня сработало это регулярное выражение:

sed 's/\\0//g'

Итак, когда вы получите ваши данные, сделайте следующее: $ get_data | sed 's/\\0//g', который выведет ваши данные без 0x00

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...