从Oracle迁移到PostgreSQL时出现无效的UTF8字符
我在这里修改我的问题。我正在使用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_ENCODING到LATIN1后成功地进行迁移,但我得到这个在PG结束:
This will be my first time visiting Seattle. э НэИ
请审查和评论
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')
- >(�
)也可能适合。
我曾尝试执行上述查询SELECT * FROM CS_ACTIONS WHERE REGEXP_LIKE(CS_COMMENTS,UNISTR('[\ 0000- \ FFFF]'));''但获得了以下输出ORA-12726:正则表达式中的不匹配支架 12726。00000 - “正则表达式中不匹配的括号” *原因:正则表达式没有平衡的括号。 *措施:确保括号正确平衡.'请协助 – user2068804
尝试'UNISTR('[\ 0001- \ FFFF]')'。 '\ 0000'似乎有特殊的含义。 –
试过这个'SELECT * FROM CS_ACTIONS WHERE REGEXP_LIKE(CS_COMMENTS,UNISTR('[\ 0001- \ FFFF]'));',但我得到整个表格内容作为输出。请让我,如果我做错了 – user2068804
对不起,我不明白你的问题,你需要这样的东西? SELECT * FROM(select asciistr(convert(table_name,'UTF8'))AS str FROM table_ex) – Moudiz
“非UTF8投诉”是什么意思?如果你的数据库字符集是'AL32UTF8',那么**所有**字符都是UTF-8,否则Oracle会自动用''' –
替换它们。我没有要求你改变数据库的字符集。我问:“非UTF8投诉是什么意思?”如果您的数据库是“UTF8”(或“AL32UTF8”),则不能存储任何非UTF8字符。 –