简体   繁体   中英

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

I am currently migrating a system from Oracle 11g to 12c.

The 11g Server (Source) uses WE8MSWIN1252 character set, the 12c Server (Target) uses AL32UTF8 character set.

We use EXP and IMP to transfer the data for one schema. German umlauts are not correctly transferred. Also some fields are getting too long for the target as they get longer trough UTF representation.

What are the correct settings for EXP and IMP to achieve a correct and lossless conversion with imp/exp?

Thanks in advance!

To change the database character set, perform the following steps:

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;

Note that the CSALTER script does not perform any user data conversion. It only changes the character set metadata in the data dictionary.Thus, after the CSALTER operation, Oracle will behave as if the database was created using the new character set.

I tried all different NLS_Settings, conversions of meta settings to no avail. Later I discovered that some tables had correct umlauts after the migration, some had typical two character thingies like "ü" for german "ü".

As the application worked well on the old database I suspect that due to an error in an older version of the application some of the umlauts were coded to different codepoints resulting in the same character but being split through the process of migration.

The simple solution I found was to create a small PL/SQL block that corrects all umlauts across all varchar fields in all tables. This is kinda brute force solution but as experimenting with IMP/EXP takes a very long time this was the most feasable way to solve my problem in reasonable time.

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;

And yes, there is no conversion for 'Ö', I did not find any in the database as only few german words start with 'ö' and even less are capitalized ;-)

Perhaps this approach can solve as a quick fix for anyone running into the same problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM