2013-03-22 104 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編碼 - 然後將它們解碼返回到應用程序中的文本。我真的不推薦這個。