由於遺留原因,我們在Oracle 10數據庫中有一個VARCHAR2列 - 其中字符編碼設置爲AL32UTF8
- 它包含一些非UTF-8值。值始終是在這些字符集之一:如何從可能的編碼列表中將Oracle VARCHAR2值轉換爲UTF-8?
- US-ASCII
- UTF-8
- CP1252
- Latin-1的
我寫了一個Perl的功能修復數據庫外部的損壞值。對於來自此數據庫列的值,它循環遍歷此編碼列表並嘗試將值轉換爲UTF-8。如果轉換失敗,它會嘗試下一個編碼。第一個沒有錯誤地轉換是我們保留的價值。現在,我想在數據庫中複製這個功能,以便任何人都可以使用它。
但是,我所能找到的這個是CONVERT
function,它永遠不會失敗,但會插入替換字符來替換它不識別的字符。因此,就我所知,無法知道轉換何時失敗。
爲此,我有兩個問題:
- 有一些試圖將字符串轉換成編碼的列表中的一個,這回成功的第一個現有的接口?
- 如果沒有,是否有一些其他接口指示失敗,如果它無法將字符串轉換爲編碼?如果是這樣,那麼我可以寫上一個函數。
UPDATE:
僅供參考,我已經寫在PL/pgSQL裏這PostgreSQL的函數,它正是我需要的:
CREATE OR REPLACE FUNCTION encoding_utf8(
bytea
) RETURNS TEXT LANGUAGE PLPGSQL STRICT IMMUTABLE AS $$
DECLARE
encoding TEXT;
BEGIN
FOREACH encoding IN ARRAY ARRAY[
'UTF8',
'WIN1252',
'LATIN1'
] LOOP
BEGIN
RETURN convert_from($1, encoding);
EXCEPTION WHEN character_not_in_repertoire OR untranslatable_character THEN
CONTINUE;
END;
END LOOP;
END;
$$;
我深深地愛知道如何在Oracle中做同樣的事情。
你的代碼發生了什麼,你*首先*嘗試通過調用'convert'來轉換你的輸入數據到al32utf8,然後檢查操作是否成功。然而,對於字節爲導向的字符集 - 哪些cp1252碰巧是,每個編碼的長度恰好爲1個字節 - 轉換爲unicode將永遠不會失敗。因此你的檢查將會成功,'reencode'功能將退出。請注意,通過成功轉換爲unicode的方式來區分字節編碼的源字符集是不可能的 - 您需要上下文信息來執行此操作。問候。 – collapsar
(續)。 1.)從技術上講,我的陳述僅適用於字形被併入unicode的(字節編碼)字符集。我不知道任何不符合這個標準的字符集(提示讚賞)。 2.)來標識源字符集,你可以2a。)在latin-1和cp1252的特定情況下,檢查未在latin-1(0x7f-0x9f)或2b中映射到字形的字節。序列而不是單個字符。例如:A4 - >歐元(拉丁文-15)/貨幣(cp1252)。後者不會出現在普通文本中的數字之後,所以' A4'將表示拉丁文-15。 –
collapsar
唉,我沒有上下文信息,所以我只是在清理一些舊東西。在十億條記錄中轉換爲CP1252是我們可以生活的。 – theory