2013-03-22 107 views
2

我已经写在PL/Perl的这个存储过程没有相应:的PostgreSQL:编码“UTF8”字符在“LATIN1”在plperl存储过程

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 encodend ),可能有一些无效字符,因为我得到的东西,如:

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" 

我使用PostgreSQL的转换()和convert_from()来尝试更改编码,但没有任何运气尝试。有任何想法吗?

在此先感谢。

回答

1

我想象这里发生了什么是strip_html_tags是HTML实体解码成表示为UTF-8编码的文本本地Unicode代码点。 0xe2809c解码为utf-8字节序列为the unicode code point U+201c LEFT DOUBLE QUOTATION MARK - the character ,这完全可以从HTML中的解码转义中获得,特别是由GUI编辑器或MS Word生成的HTML。它将被表示为HTML中的““(十进制)或“(十六进制)。

因为你的数据库编码为Latin-1的,你不能代表很多在数据库中这些解码字符。

你真的应该考虑改变你的数据库为UTF-8,如果你打算与完整的Unicode数据进行工作。如果你的数据库真的在latin-1不是(ugh)SQL_ASCII;只需转储数据库,使用ENCODING 'utf-8'创建一个新的数据库,并将数据加载到数据库中以验证并检查它。根据转换的数据库测试您的应用程序,并确保它们正确处理unicode文本。当你快乐时,停止你的应用程序,再次转储数据库,重新加载它,重命名旧的数据库,然后重命名新的数据库,使其具有与旧版本相同的名称。

如果你愿意你的裂伤HTML就可以use Perl modules features to do a lossy encoding conversion from UTF-8 to Latin-1。有Perl模块可以替代",(em破折号)和-(减号)等,并且可以去掉不可替换的字符或用替换字符(如“?”)替换它们。这是一个单向有损转换;如果您没有保留原始不变版本的副本,则无法获取原始数据。

你的唯一选择就是返回数据bytea - 字节字符串的UTF-8编码 - 然后将它们解码返回到应用程序中的文本。我真的不推荐这个。