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

**URL:** <https://entwicklergate.de/t/migrieren-einer-oracle-xe-10-installation-nach-oracle-xe-11-unter-windows/131>\
**Category:** Entwicklung\
**Tags:** oracle, oracle-xe, docker\
**Created:** [6. April 2016 um 11:34 UTC](https://entwicklergate.de/t/migrieren-einer-oracle-xe-10-installation-nach-oracle-xe-11-unter-windows/131 "2016-04-06T11:34:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![UweKeim](https://entwicklergate.de/user_avatar/entwicklergate.de/uwekeim/32/432_2.png) [@UweKeim](https://entwicklergate.de/u/UweKeim)\
**Post date:** [6. April 2016 um 11:34 UTC](https://entwicklergate.de/t/migrieren-einer-oracle-xe-10-installation-nach-oracle-xe-11-unter-windows/131/1 "2016-04-06T11:34:05Z")

</div>

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](https://docs.oracle.com/cd/E17781_01/install.112/e18803/toc.htm#XEINW136))

### 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.

```sql
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](https://de.wikibooks.org/wiki/Oracle:_CharacterSet_%C3%A4ndern) hat mir Fehler geworfen, [der offizielle Weg](http://docs.oracle.com/cd/B28359_01/server.111/b28298/ch11charsetmig.htm#CEGDHJFF) 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.

---

<div class="post-metadata">

**Author:** ![UweKeim](https://entwicklergate.de/user_avatar/entwicklergate.de/uwekeim/32/432_2.png) [@UweKeim](https://entwicklergate.de/u/UweKeim)\
**Post date:** [6. April 2016 um 11:49 UTC](https://entwicklergate.de/t/migrieren-einer-oracle-xe-10-installation-nach-oracle-xe-11-unter-windows/131/2 "2016-04-06T11:49:45Z")

</div>

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](http://www.anattatechnologies.com/q/2012/01/sqlplus-pagesize-and-linesize/).

---

<div class="post-metadata">

**Author:** ![UweKeim](https://entwicklergate.de/user_avatar/entwicklergate.de/uwekeim/32/432_2.png) [@UweKeim](https://entwicklergate.de/u/UweKeim)\
**Post date:** [27. Januar 2023 um 16:07 UTC](https://entwicklergate.de/t/migrieren-einer-oracle-xe-10-installation-nach-oracle-xe-11-unter-windows/131/3 "2023-01-27T16:07:49Z")

</div>

### Oracle 11 nach Oracle 21c

Habe Daten von einer Oracle-XE-Instanz unter Windows auf ein neu aufgesetztes Oracle-XE unter Ubuntu-Linux mit Docker migriert.

Also das [Oracle läuft als Docker-Container](https://container-registry.oracle.com/):

> docker run --name OracleZeta -d --restart=always -p 1521:1521 -p 5500:5500 -e ORACLE\_PWD=HereComesAPassword -v ZetaOracleVolume:/opt/oracle/oradata [container-registry.oracle.com/database/express:21.3.0-xe](http://container-registry.oracle.com/database/express:21.3.0-xe)

(Bitte auch via `sudo systemctl enable docker` sicherstellen, dass [Docker beim Systemstart läuft](https://forums.docker.com/t/run-container-at-system-startup/90630/3)).

Ich habe dazu zunächst alle Benutzer/Schemas via [„sqlplus“-Befehlszeilenprogramm](https://www.oracle.com/de/database/technologies/instant-client/winx64-64-downloads.html) auf der Zieldatenbank angelegt.

„sqlplus“ habe ich von einem Windows-Client aus gestartet und mich mit der Oracle XE in Docker verbunden:

> „C:\Ablage\sqlplus.exe“ sys/HereComesAPassword@//MyServer/XE as sysdba

Anschließend dann die [User anlegen](https://stackoverflow.com/a/23955869/107625), die [Berechtigungen vergeben](https://www.oracletutorial.com/oracle-administration/oracle-grant-all-privileges-to-a-user/), und darauf geachtet, zuvor [`alter session set "_ORACLE_SCRIPT"=true; `](https://stackoverflow.com/a/41490385/107625) ausgeführt zu haben.

Die Migration der Daten habe ich dann via Oracle SQL Developer und der Funktion „Extras“ \> „Datenbankkopie“ gemacht:

 ![image](https://entwicklergate.de/uploads/default/original/1X/9ac73f474d07d050863f9b499b8c31fdc9190516.jpeg)

Dort konnte ich eine Quellverbindung zur bestehenden, alten Oracle-XE-Instanz auswählen, und anschließend eine Zielverbindung zur neuen Oracle-XE-Instanz unter Ubuntu, und anschließend konfigurieren, dass ich DDL und Daten migrieren möchte.

Das lief eigentlich recht gut durch. Traten Fehler auf, habe ich jeweils die Option (sinngemäß) „Fehler ignorieren und Verarbeitung fortsetzen“ ausgewählt).

Da es Foreign-Key-Fehler gab, und ich annahm, dass das aufgrund falscher Reihenfolge der Tabellen auftrat, habe ich einfach den „Datenbankkopie“-Assistenten mehrfach gestartet. Beim zweiten Mal dann nur noch die Daten, nicht mehr die DDL.

---

<div class="post-metadata">

**Author:** ![UweKeim](https://entwicklergate.de/user_avatar/entwicklergate.de/uwekeim/32/432_2.png) [@UweKeim](https://entwicklergate.de/u/UweKeim)\
**Post date:** [27. Januar 2023 um 17:21 UTC](https://entwicklergate.de/t/migrieren-einer-oracle-xe-10-installation-nach-oracle-xe-11-unter-windows/131/4 "2023-01-27T17:21:16Z")

</div>

### Oracle 11 nach Oracle 21c

Mist, die Lösung über den Export-Wizard war doch nicht so der Bringer (Daten unvollständig), ich habe nochmals den Data Pump laufen lassen, nur mit Daten:

> `expdp.exe UKEIM/MeinKennwort@MeinQuellServer:1521/XE DIRECTORY=migr DUMPFILE=migr.dmp LOGFILE=migr.log schemas=UKEIM`

Das dann per `scp` auf den Linux-Server nach `/var/tmp` kopiert:

> `scp c:\Ablage\MIGR.DMP administrator@MeinZielServer:/var/tmp/`

Und anschließend per SSH auf den Linux-Server gegangen und von dort per `docker cp` in den Oracle-Docker-Container nach `/var/tmp` kopiert:

> `docker cp /var/tmp/MIGR.DMP MeinContainerName:/var/tmp/MIGR.DMP`

Dann [alle Tabellen gelöscht](https://stackoverflow.com/a/1690419/107625).

Und anschließend den Import laufen lassen:

> `impdp.exe UKEIM/MeinKennwort@MeinZielServer:1521/XE DIRECTORY=migr DUMPFILE=MIGR.DMP LOGFILE=migr.log schemas=UKEIM`

Leider fehlen auch hier jetzt immer noch Daten (Import teilweise mit Constraint-Violation-Fehlern fehlgeschlagen), ggf. lasse ich das ganze nochmals laufen, komplett mit Schema und so.
