2017-06-07 511 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