Joh*_* F. 3 oracle migration character-set
这是我之前发布的帖子的后续问题。我们正在迁移到新的字符集。现在,我是一名程序员,我们有 DBA 将执行这项工作,但我想获得有关该过程的更多信息。我们当前的字符集是 WE8ISO8859P1 并使用 BYTE 字符语义。但是,我们正在迁移到 AL32UTF8。使用 BYTE 语义创建了一个包含 AL32UTF8 字符集的新数据库。DBA 在一些表上运行了一个脚本来检查是否有任何问题(我相信是 CSALTER)。运行脚本后,它说我们表中的某些行将被截断。该表包含一个设置为 4000 BYTES 的 VARCHAR2(BYTE) 列。导致潜在问题的行都包含特殊字符。我的问题是,我们如何在不截断信息的情况下导出/导入数据库中的表?为什么说它会被截断?我的第一个想法是,由于我们更改了字符集,它可能会存储旧数据库表中的某些字符,而不是将其存储到新数据库中时,字符集会占用更多存储空间。
截断的原因很简单。WE8ISO8859P1 字符集中的某些字符(例如重音字符)存储为单个字节,但在 AL32UTF8 中它们最终存储为多个字节。作为转换的结果,一个 4000 个字符的字符串最终可能实际需要超过 4000 个字节。
例如,此查询显示欧元符号(WE8ISO8859P1 中的 0x80)在 AL32UTF8 中变为 2 个字节:
SQL> select length(convert(chr(128),'AL32UTF8','WE8ISO8859P1')) from dual
2 /
LENGTH(CONVERT(CHR(128),'AL32UTF8','WE8ISO8859P1'))
---------------------------------------------------
2
SQL>
Run Code Online (Sandbox Code Playgroud)
要列出将受更改影响的所有字符,您可以使用以下查询:
with n as
(
select level as c from dual
connect by level <= 255
)
select c as "WE8ISO8859P1 value",
'"'||chr(c)||'"' as Character,
length(convert(chr(c),'AL32UTF8','WE8ISO8859P1')) as "New length"
from n
where length(convert(chr(c),'AL32UTF8','WE8ISO8859P1'))>1;
Run Code Online (Sandbox Code Playgroud)
不幸的是,aCHAR
或VARCHAR
字符串在 Oracle 中的最大长度是 4000 字节。如果字符集转换使您超过此限制,唯一可用的选项是将列转换为使用CLOB
数据类型,但我们警告说 -CLOB
很难处理并且可能会带来挑战。
归档时间: |
|
查看次数: |
4175 次 |
最近记录: |