Migrieren einer Oracle XE 10-Installation nach Oracle XE 11 unter Windows

Oracle XE, die kostenlose Express-Version, ist aus meiner Sicht im Vergleich zum SQL Server von Microsoft deutlich „spröder“ in der Bedienung.

Z. B. kann ich nicht einfach eine Version 10 auf Version 11 per Setup updaten.

Stattdessen muss mit der Verwendung von Befehlszeilen-Programmen ein Export erstellt werden und anschließend ein Import.

Nachfolgend habe ich die Schritte aufgeschrieben.

(Es gibt auch eine offizielle Kurzanleitung von Oracle)

Randbedingungen

  • Quellsystem und Zielsystem sind unterschiedliche Rechner.
  • Ordnerstruktur Quellsystem und Zielsystem sind ähnlich/identisch.

Export vom Quellsystem

SQL Plus starten:

C:\oraclexe\app\oracle\product\10.2.0\server\BIN\sqlplus.exe system/meinkennwort@XE

Und dann einen Export-Ordner anlegen als Alias auf einen tatsächlichen:

`CREATE DIRECTORY migr_xe_to_11 AS 'C:\Ablage';`

Dann SQL Plus wieder beenden:

EXIT

Mit dem Expdp-Programm den Export anstoßen:

C:\oraclexe\app\oracle\product\10.2.0\server\BIN\expdp.exe system/meinkennwort@XE DIRECTORY=migr_xe_to_11 DUMPFILE=migr_xe%U FILESIZE=500MB LOGFILE=migr_xe_to_11.log FULL=Y

Es werden dann eine oder mehrere DMP-Dateien angelegt. In meinem Fall waren es:

  • C:\ABLAGE\MIGR_XE01.DMP
  • C:\ABLAGE\MIGR_XE02.DMP
  • C:\ABLAGE\MIGR_XE03.DMP

Diese Dateien jetzt auf das Zielsystem kopieren.

Import im Zielsystem

SQL Plus starten:

C:\oraclexe\app\oracle\product\11.2.0\server\bin\sqlplus.exe system/meinkennwort@XE

Ordner anlegen:

CREATE DIRECTORY migr_xe_to_11 AS 'C:\Ablage';

SQL Plus wieder beenden:

EXIT

Jetzt mit dem Impdp-Programm die DMP-Dateien importieren:

C:\oraclexe\app\oracle\product\11.2.0\server\bin\impdp.exe system/meinkennwort@XE DIRECTORY=migr_xe_to_11 DUMPFILE=migr_xe%U LOGFILE=imp_xe_to_11.log

Fehlerlokalisierung Import

Bei mir hat der Import teilweise funktioniert, teilweise kamen Fehlermeldungen à la:

ORA-02374: conversion error loading table „UKEIM“.„SHADOW_STEWII_AUD“
ORA-12899: value too large for column ZUORD (actual: 7, maximum: 6)
ORA-02372: data for row: ZUORD : 0X’34313554DC31’

Um das herauszubekommen, habe ich folgenden Befehl in SQL Plus ausgeführt:

SELECT * FROM NLS_DATABASE_PARAMETERS;

Und zwar auf dem Quell- und Zielsystem.

Außerdem haben wir auf dem Zielsystem noch den Befehl

show parameters pool;

und den Befehl

show parameters buffer;

ausgeführt.

Das hat die Ursache aufgezeigt: der Fehler war, dass das Encoding (Wert von NLS_CHARACTERSET) der Quelldatenbank „WE8MSWIN1252“ war und das Encoding der Zieldatenbank „AL32UTF8“.

Dadurch wurden wohl Feldinhalte aufgebläht und haben die maximale Feldgröße überschritten.

Fehlerbehebung

Wir haben das dann wie folgt behoben:

  1. Auf Quelldatenbank wurden in allen Tabellen in allen Text-Spalten die maximalen Größen erhöht. Siehe nachfolgende Stored Procedure.
  2. Danach nochmals neu exportiert.
  3. Anschließend erneut importiert.

Nun hat bei mir der Import funktioniert.

create or replace PROCEDURE INCREASE_VARCHAR_1_5 AS 
V_NEW_LENGTH NUMBER; 
BEGIN
  FOR V_TABLE IN (SELECT * FROM USER_TABLES) LOOP
      
      FOR V_COLUMN IN (SELECT * FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = V_TABLE.TABLE_NAME AND DATA_TYPE LIKE '%VARCHAR%') LOOP
        V_NEW_LENGTH := CEIL(V_COLUMN.DATA_LENGTH * 1.5);
        
        IF V_COLUMN.DATA_TYPE LIKE 'NVARCHAR%' THEN
          IF V_NEW_LENGTH > 2000 THEN
            V_NEW_LENGTH := 2000;
          END IF;
        ELSE
          IF V_NEW_LENGTH > 4000 THEN
            V_NEW_LENGTH := 4000;
          END IF;
        END IF;
        
        IF V_COLUMN.DATA_TYPE LIKE 'NVARCHAR%' THEN
          V_NEW_LENGTH := V_COLUMN.CHAR_LENGTH;
          --NVARCHAR ist immer CHAR https://community.oracle.com/thread/837666?start=0&tstart=0
          EXECUTE IMMEDIATE 'ALTER TABLE "' || V_TABLE_NAME || '" MODIFY ("' || V_COLUMN_NAME || '" ' || V_COLUMN.DATA_TYPE || '(' || V_NEW_LENGTH || '))';
        ELSE
          V_NEW_LENGTH := V_COLUMN.DATA_LENGTH;
          EXECUTE IMMEDIATE 'ALTER TABLE "' || V_TABLE_NAME || '" MODIFY ("' || V_COLUMN_NAME || '" ' || V_COLUMN.DATA_TYPE || '(' || V_NEW_LENGTH || ' CHAR))';
        END IF;
      END LOOP;
  END LOOP;
END INCREASE_VARCHAR_1_5;

Offene Punkte

Ich konnte noch nicht testen, ob das geänderte Encoding sich negativ auf Umlaute usw. auswirkt.

Eventuell sind in der Zieldatenbank die Umlaute kaputt.

In meinem Fall macht mir das nichts aus, weil es eh nur Testdaten sind.

Theoretisch bessere Fehlerbehebung

Eigentlich hätten wir das Encoding der Zieldatenbank ändern sollen, so dass es dem der Quelldatenbank entspricht.

Alternativ hätte ich auch eine neue Zieldatenbank anlegen können.

Ersteres war mir zu kompliziert, der inoffizielle Weg hat mir Fehler geworfen, der offizielle Weg mit irgendwelchen SQL-Skripten habe ich nicht kapiert.

Eine neue Zieldatenbank konnte ich auch nicht anlegen, weil in der Express-Edition (XE) von Oracle das „dbca“-Tool zum Erstellen neuer Datenbanken nicht vorhanden ist.

Und beim Installieren von XE habe ich keine Möglichkeit gefunden, das Encoding anzugeben.

Abschließende Gedanken

Ich habe den Import zunächst nicht auf meinem tatsächlichen Zielsystem getestet, sondern in einer VMware-Maschine.

Erst danach habe ich auf dem System, auf dem Oracle XE 10 lief, dieses deinstalliert (vorher Export, logisch) und dann Oracle XE 11 installiert und dann dort importiert.

Um übrigens schöner formatierte Ausgaben in SQL Plus zu bekommen, die Befehle

set pagesize 50000;

und

set linesize 120;

innerhalb von SQL Plus ausführen.

Tipp von hier.