2017-06-07 95 views
0

我在這裏修改我的問題。我正在使用AWS DMS工具從Oracle遷移到PostgreSQL。源(oracle)字符集是AL32UTF8並且目標(Pg)字符集設置爲UT8從Oracle遷移到PostgreSQL時出現無效的UTF8字符

所以在源我有一個數據類型VARCHAR2(4000),在那裏我已經存儲了這樣的東西列:

This will be my first time visiting Seattle. 

當我試圖遷移此,我得到以下錯誤:

ERROR: invalid byte sequence for encoding "UTF8": 0xed 0xa0 0xbd 

有一個在DMS的方式來跳過這一點,但問題是我需要運行DMS每次和等待它給無效字節序列錯誤,然後讓過去吧。到目前爲止,我有這麼多:

0xed 0xa4 0x88 
0xed 0xbd 0x95 
0xed 0xa9 0x8e 
0xed 0xbc 0xb8 
0xed 0xaa 0xbe 
0xed 0xba 0xb5 
0xed 0xaf 0x83 
0xed 0xb5 0xaa 
0xed 0xa0 0xbc 
0xed 0xbc 0x9f 
0xed 0xa0 0xbd 
0xed 0xb8 0xa0 
0xed 0xbe 0x88 
0xed 0xb1 0x8e 
0xed 0xb1 0x8e 
0xed 0xb1 0x8d 
0xed 0xb3 0x99 
0xed 0xb1 0x9f 
0xed 0xbe 0xa7 
0xed 0xb1 0x8c 
0xed 0xa0 0xbe 
0xed 0xb4 0x96 
0xed 0xba 0x80 
0xed 0xb4 0xb1 
0xed 0xb0 0xa7 
0xed 0xbe 0xb8 
0xed 0xbe 0xb5 
0xed 0xb7 0xbb 
0xed 0xb1 0x86 
0xed 0xbe 0xb6 
0xed 0xbf 0x8a 
0xed 0xb0 0xab 
0xed 0xb0 0x95 
0xed 0xb0 0x94 
0xed 0xb0 0x99 
0xed 0xb0 0xb1 
0xed 0xbf 0x84 
0xed 0xba 0x82 
0xed 0xb4 0xa8 
0xed 0xb0 0xaf 
0xed 0xb0 0xb8 
0xed 0xb3 0x9e 
0xed 0xb4 0xa7 
0xed 0xbe 0x81 
0xed 0xb1 0x87 

從這裏開始,論壇的帖子之一,我得到了下面的查詢:

select CASE 
      INSTR (
        RAWTOHEX (
         utl_raw.cast_to_raw (
          utl_i18n.raw_to_char (
           utl_raw.cast_to_raw (<your_column>) 
           , 'utf8' 
         ) 
        ) 
       ) 
       , 'EFBFBD' 
      ) 
     WHEN 0 THEN 'OK' 
     ELSE 'FAIL' 
     END 
    from <your_table> 
     ; 

是否有可能修改上面的查詢拿出正則表達式來檢查所有這些非法的UTF8編碼。

此外,我能夠改變CLIENT_ENCODINGLATIN1後成功地進行遷移,但我得到這個在PG結束:

This will be my first time visiting Seattle. э НэИ 

請審查和評論

+0

對不起,我不明白你的問題,你需要這樣的東西? SELECT * FROM(select asciistr(convert(table_name,'UTF8'))AS str FROM table_ex) – Moudiz

+1

「非UTF8投訴」是什麼意思?如果你的數據庫字符集是'AL32UTF8',那麼**所有**字符都是UTF-8,否則Oracle會自動用''' –

+0

替換它們。我沒有要求你改變數據庫的字符集。我問:「非UTF8投訴是什麼意思?」如果您的數據庫是「UTF8」(或「AL32UTF8」),則不能存儲任何非UTF8字符。 –

回答

0

Oracle(或任何其他支持UTF-8的系統)無法存儲無效的 UTF-8字符,遷移時必定存在問題。仔細檢查每個關於字符集的設置,編碼 - 包括您的終端設置和/或編輯器。

characer U+1F60A SMILING FACE WITH SMILING EYES屬於塊Emoticons這是在補充多語言平面。也許您的遷移工具對Basic Multilingual Plane以外的字符有一個普遍問題,即字符數超過U+FFFF

一個辦法,找出他們將

SELECT * 
FROM ... 
WHERE REGEXP_LIKE(<your_column>, UNISTR('[\0001-\FFFF]')); 

僅此條件返回字符從基本多文種平面。

您也可以嘗試這樣的:

SELECT 
    REGEXP_SUBSTR('This will be my first time visiting Seattle. ', UNISTR('[\FFFF-\DBFF\DFFF]')) 
FROM dual; 

REGEXP_SUBSTR('THISWILLBEMYFIRSTTIMEVISITINGSEATTLE.',UNISTR('[\FFFF-\DBFF\DFFF] 
-------------------------------------------------------------------------------- 
                        
1 row selected. 

更新

我再次檢查。

  • U+1F60A SMILING FACE WITH SMILING EYES
  • 可被寫入爲UNISTR('\D83D\DE0A')
  • 編碼爲UTF-8(甲骨文字符集AL32UTF8):F0 9F 98 8A
  • 編碼爲CESU-8(甲骨文字符集UTF8):ED A0 BD ED B8 8A

你的錯誤消息指出:UTF8 「編碼無效字節序列 」「:0xed 0XA0 0xbd」

ED A0 BD是CESU-8序列。顯然,您從Oracle的導出是以CESU-8 的形式提供的,但不是以UTF-8的形式提供的。再次檢查您的設置。

更新2

爲了從現有的數據替換增補字符,你可以試試這個:

UPDATE FDRGIIT.CS_ACTIONS 
SET CS_COMMENTS = REGEXP_REPLACE(CS_COMMENTS, UNISTR('[\FFFF-\DBFF\DFFF]'), UNISTR('\00BF')); 

UPDATE FDRGIIT.CS_ACTIONS 
SET CS_COMMENTS = REGEXP_REPLACE(CS_COMMENTS, UNISTR('[\FFFF-\DBFF\DFFF]')); 

UNISTR('\00BF')是所使用的佔位符(¿)由Oracle爲無效字符。 UNISTR('\FFFD') - >()也可能適合。

+0

我曾嘗試執行上述查詢SELECT * FROM CS_ACTIONS WHERE REGEXP_LIKE(CS_COMMENTS,UNISTR('[\ 0000- \ FFFF]'));''但獲得了以下輸出ORA-12726:正則表達式中的不匹配支架 12726。00000 - 「正則表達式中不匹配的括號」 *原因:正則表達式沒有平衡的括號。 *措施:確保括號正確平衡.'請協助 – user2068804

+0

嘗試'UNISTR('[\ 0001- \ FFFF]')'。 '\ 0000'似乎有特殊的含義。 –

+0

試過這個'SELECT * FROM CS_ACTIONS WHERE REGEXP_LIKE(CS_COMMENTS,UNISTR('[\ 0001- \ FFFF]'));',但我得到整個表格內容作爲輸出。請讓我,如果我做錯了 – user2068804