PostgreSQL: символ кодировки UTF8 не имеет эквивалента в LATIN1 в хранимой процедуре plperl

У меня есть эта хранимая процедура, написанная на Pl/Perl:

CREATE FUNCTION strip_html_tags(text) RETURNS TEXT AS $$
    use HTML::Strip;
    my $hs = HTML::Strip->new();
    my $clean_text = $hs->parse($_[0]);
    $hs->eof;
    return $clean_text;
$$ LANGUAGE plperlu;

У меня есть некоторые поля в моей базе данных (кодировка LATIN1), которые, вероятно, содержат недопустимые символы, потому что я получаю такие вещи, как:

db=# select strip_html_tags(field) from table;
ERROR:  character 0xe2809c of encoding "UTF8" has no equivalent in "LATIN1"
CONTEXT:  PL/Perl function "strip_html_tags"

Я пытался использовать Convert() и convert_from() PostgreSQL, чтобы попытаться изменить кодировку, но безуспешно. Любые идеи?

Заранее спасибо.


person Gonçalo Marrafa    schedule 22.03.2013    source источник


Ответы (1)


Я предполагаю, что здесь происходит то, что strip_html_tags декодирует объекты HTML в собственные кодовые точки Unicode, выраженные в виде текста в кодировке utf-8. 0xe2809c, расшифрованная как последовательность байтов utf-8, представляет собой кодовую точку Юникода U+201c LEFT DOUBLE QUOTATION MARK - символ , что вполне правдоподобно, как нечто, что вы получите от декодированного побега в HTML, особенно в HTML, созданном редакторами с графическим интерфейсом или MS Word. В HTML он будет представлен как “, “ (десятичное) или “ (шестнадцатеричное).

Поскольку в вашей базе данных используется кодировка latin-1, вы не можете представить многие из этих декодированных символов в базе данных.

Вам действительно следует подумать об изменении вашей базы данных на utf-8, если вы собираетесь работать с полными данными Unicode. Обычно это несложно, если ваша БД действительно находится в latin-1, а не (тьфу) SQL_ASCII; просто выгрузите базу данных, создайте новую БД с ENCODING 'utf-8' и загрузите в нее данные для проверки и проверки. Протестируйте свои приложения на преобразованной базе данных и убедитесь, что они правильно работают с текстом Unicode. Когда вы будете счастливы, остановите свое приложение, снова создайте дамп базы данных, перезагрузите ее снова, переименуйте старую БД, а затем переименуйте новую БД, чтобы она имела то же имя, что и старая.

Если вы хотите изменить свой HTML, вы можете использовать функции модулей Perl для преобразования кодировки с потерями из UTF-8 в Latin-1< /а>. Существуют модули Perl, которые будут делать такие вещи, как замена на ", (длинное тире) на - (знак минус) и т. д., и могут удалять незаменяемые символы или заменять их заменяющими символами, такими как "?". Это одностороннее преобразование с с потерями; вы не сможете вернуть исходные данные, если не сохраните копию исходной неизмененной версии.

Единственная другая альтернатива - вернуть данные в виде bytea - байтовых строк в кодировке utf-8, а затем декодировать их обратно в текст в вашем приложении. Я действительно не рекомендую это делать.

person Craig Ringer    schedule 22.03.2013