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;
是的,'Ö' 没有转换,我在数据库中没有找到任何转换,因为只有少数德语单词以 'ö' 开头,大写的更少;-)
也许这种方法可以作为任何人 运行 遇到相同问题的快速解决方案。
我目前正在将系统从 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;
是的,'Ö' 没有转换,我在数据库中没有找到任何转换,因为只有少数德语单词以 'ö' 开头,大写的更少;-)
也许这种方法可以作为任何人 运行 遇到相同问题的快速解决方案。