Oracle 11g 到 Oracle 12c 字符集转换(转储)

Oracle 11g to Oracle 12c character set conversion (dump)

我目前正在将系统从 Oracle 11g 迁移到 12c。

11g服务器(源)使用WE8MSWIN1252字符集, 12c 服务器(目标)使用 AL32UTF8 字符集。

我们使用 EXP 和 IMP 来传输一个模式的数据。德语变音符号未正确转移。此外,一些字段对于目标而言变得太长,因为它们通过 UTF 表示变得更长。

EXP 和 IMP 的正确设置是什么才能实现 imp/exp 的正确无损转换?

提前致谢!

要更改数据库字符集,请执行以下步骤:

1.Shut down the database, using either a SHUTDOWN IMMEDIATE or a SHUTDOWN NORMAL statement.

2.Do a full backup of the database, because the CSALTER script cannot be rolled back.

3.Start up the database.

4.Run the Database Character Set Scanner utility.
CSSCAN /AS SYSDBA FULL=Y...

5.Run the CSALTER script.
@@CSALTER.PLB
SHUTDOWN IMMEDIATE; -- or SHUTDOWN NORMAL;
STARTUP;

请注意,CSALTER 脚本不执行任何用户数据转换。它仅更改数据中的字符集元数据 dictionary.Thus,在 CSALTER 操作之后,Oracle 的行为就好像数据库是使用新字符集创建的一样。

我尝试了所有不同的 NLS_Settings,元设置的转换都无济于事。后来我发现有些表在迁移后有正确的元音变音,有些表有典型的两个字符,例如德语“ü”的“ϼ”。

由于该应用程序在旧数据库上运行良好,我怀疑由于旧版本应用程序中的错误,一些变音符号被编码为不同的代码点,导致相同的字符但在迁移过程中被拆分.

我找到的简单解决方案是创建一个小的 PL/SQL 块来更正所有表中所有 varchar 字段的所有元音变音。这是一种蛮力解决方案,但由于 IMP/EXP 的试验需要很长时间,这是在合理时间内解决我的问题的最可行方法。

begin
  for c in (select a.table_name,b.column_name from all_tables a 
  left join all_tab_columns b on a.table_name=b.table_name and b.owner='<myschema>'
  where a.owner = '<myschema>' 
  and (b.data_type='VARCHAR2' or b.data_type='VARCHAR'))
  loop
    execute immediate 'update ' || c.table_name ||
    ' set ' || c.column_name || '=
      replace(
        replace(
          replace(
             replace(
               replace(
                 replace(' || c.column_name || ',''Ä'',''Ä''),
               ''ä'',''ä''),
             ''ü'',''ü''),
          ''ß'',''ß''),
       ''Ãœ'',''Ü''),
     ''ö'',''ö'')';
  end loop;
end;

是的,'Ö' 没有转换,我在数据库中没有找到任何转换,因为只有少数德语单词以 'ö' 开头,大写的更少;-)

也许这种方法可以作为任何人 运行 遇到相同问题的快速解决方案。