Blog

MS SQL Migration nach Oracle

Attila
IT–Consultant

In den meisten Artikeln über die Migration von MSSQL nach Oracle wird die Vorgehensweise einfach dargestellt. Beispielsweise wie ein Windows Applikations Installer "Next > Next > Finish" und damit sei die Sache abgehakt. Wer aber eine Migration schon einmal ausprobiert hat, wird schnell merken, dass das nicht so einfach ist. Die Antwort liegt meistens in den Datentypen und wie sie von Oracle migriert und erkannt werden. Alternativ können auch Berechtigungsprobleme vorliegen oder aber falsch interpretierte Prozeduren/Funktionen von TSQL.

In diesem Artikel werden wir Microsofts AdventureWorks Datenbank mit Oracle SQL Developer nach Oracle migrieren und dabei die häufigsten und bei uns aufgetretenen Fehler und deren Problemlösung beschreiben.

Vorbereitung der Oracle Datenbank

Für die Migration haben wir eine separate Pluggable Datenbank erstellt:

CREATE PLUGGABLE DATABASE MSSQL ADMIN USER msadmin IDENTIFIED BY "msadmin" ROLES=(DBA);

Der SQL Developer braucht ein Schema, in dem das Migrations-Repository erstellt werden kann. Dieses Schema kann nach der Migration gelöscht werden. Wir können also ruhig alle Rechte vergeben - alles andere wird automatisch von SQL Developer erstellt.

grant dba to migration_repo identified by migration_repo;

Oracle hat mit dem ersten Release von 12c die maximale Länge der Datentypen VARCHAR2, NVARCHAR2 und RAW auf 32767 Bytes erweitert. Um dieses Feature nutzen zu können, muss jedoch zuvor der Parameter max_string_size auf extended geändert werden und im Upgrade-Mode das Skript utl32k.sql ausgeführt werden:

SQL> alter pluggable database close immediate;

Pluggable database altered.

SQL> alter pluggable database open upgrade;

Pluggable database altered.

SQL> ALTER SYSTEM SET max_string_size='EXTENDED' SCOPE=both SID='*';

System altered.

SQL> @?/rdbms/admin/utl32k.sql

SQL> alter pluggable database close immediate;

Pluggable database altered.

SQL> alter pluggable database open;

Pluggable database altered.

SQL>

Die Konfiguration der PDB ist damit fertig.

SQL Developer Konfiguration

SQL Developer kann hier heruntergeladen werden.

Um sich mit dem SQL Developer auf die MSSQL Instanz zu verbinden, brauchen wir folgendes Plugin: Download : jtds-1.3.1-dist.zip

Diese Datei müssen wir zunächst entpacken und dann im SQL Developer unter Preferences > Database > Third Party JDBC Drivers das jar-File im ausgepackten Verzeichnis auswählen.

Erstellen wir eine Verbindung zu dem Migrations-Repository

Erstellen wir anschließend eine Verbindung für die MSSQL Quellinstanz (Adventure Works)

Danach erstellen wir eine Verbindung für die Oracle Zielinstanz der Migration:

Wenn alle drei Verbindungen erstellt sind, können wir das Repository erstellen. Dies nehmen wir durch die Auswahl von “Migration Repository” > “Associate Migration Repository” im Kontextmenü der migration_repo Verbindung vor.

Nach dem Klick wird das Repository installiert.

Migration nach Oracle

Wenn das Repository erstellt ist, können wir mit einem Rechtsklick auf die Quellinstanz klicken und Migrate to Oracle auswählen.

Der erste Schritt gibt einen Überblick über die auszuführenden Schritte. Hier empfehlen wir einfach den Next-Button zu drücken.

Danach wählen wir die Verbindung zum Migrations-Repository aus.

Im nächsten Fenster des Migrations-Wizards wird nach einem frei wählbaren Projektnamen gefragt.

Ferner muss ein Zielverzeichnis für Log- und Migrationsdateien erstellt werden

In Schritt 4 wählen wir die Verbindung zur Quellinstanz (hier MSSQL) aus

Wenn in der Quellinstanz mehrere Datenbanken sind, können wir im nächsten Schritt die DB auswählen, die wir migrieren möchten.

Danach kann man die Datentypkonversionen anpassen. Es gibt ein paar Datentypen, die nicht erkannt werden und diese kann man leider weder unter Add New Rule, noch unter advanced options zu den Datentypen hinzufügen. So werden diese Typen als RAW erkannt und mit einer Länge von 8000 erstellt.

In Schritt 7 wählen wir, welche Objekte wir konvertieren möchten.

Im nächsten Schritt wählen wir die Verbindung zur Zielinstanz aus. Hier können wir noch einstellen, ob eventuell vorhandene Zielobjekte gleichen Namens zuvor gelöscht werden sollen. Da wir aber eine neuen PDB benutzen, brauchen wir das nicht.

In Schritt 9 wählen wir aus, ob die Daten Online oder Offline kopiert werden sollen. Dazu müssen wir noch die Quelle und das Ziel auswählen und auf Next drücken.

Die Zusammenfassung bestätigen wir mit Finish und warten bis die Konvertierung erfolgreich endet.

Logs prüfen und Fehler beheben

Wenn die Migration fertig ist, sollten wir im Projektverzeichnis das Master Log (Der Name besteht aus dem angegebenen Projektnamen und dem Ausführungsdatum. Bei uns heißt es AW_Migration_2023-03-06_22-43-20.log) und das MigrationLog.xml anschauen und prüfen, ob die Datenbankobjekte richtig erstellt wurden.

Im Master Log wurden bei unserer Migration einige ORA-01450 Fehlermeldungen protokolliert:

Error starting at line : 2,795 File @ C:\Users\AttilaLégrádi\Documents\ms_migration\mssql2\MSSQL\generated\2023-03-02_15-27-36\master.sql
In command -
CREATE INDEX IX_Employee_OrganizationLevel_OrganizationNode ON Employee
(
OrganizationLevel,
OrganizationNode
)
Error report -
ORA-01450: maximum key length (6398) exceeded
01450. 00000 - "maximum key length (%s) exceeded"

Prüfen wir die Einstellungen des Spaltentyps

select column_name, data_type, data_length, char_length from dba_tab_cols
where owner='HUMANRESOURCES_ADVENTUREWORKS2019'
and table_name = 'EMPLOYEE' and column_name = 'ORGANIZATIONNODE';
COLUMN_NAME DATA_TYPE DATA_LENGTH CHAR_LENGTH
ORGANIZATIONNODE RAW 8000 0

Prüfen wir noch, welches der längste String in der Spalte ist und besprechen mit den Anwendungsentwicklern, ob die Länge geändert oder verkürzt werden kann.

select 'ORGANIZATIONNODE', max ( length ( ORGANIZATIONNODE ) ) mx_char_length
, max ( lengthb ( ORGANIZATIONNODE ) ) mx_byte_length
from HUMANRESOURCES_ADVENTUREWORKS2019.EMPLOYEE;
'ORGANIZATIONNODE MX_CHAR_LENGTH MX_BYTE_LENGTH
ORGANIZATIONNODE 8 8

Offensichtlich ist eine Datenlänge von 8000 zu viel des Guten. Wir ändern die Spalte und konfigurieren sie kleiner.

alter table HUMANRESOURCES_ADVENTUREWORKS2019.EMPLOYEE modify ORGANIZATIONNODE RAW(20);

Wenn die Tabelle geändert ist, kann man den Index neu erstellen

CREATE INDEX IX_Employee_OrganizationNode
ON HUMANRESOURCES_ADVENTUREWORKS2019.Employee ( OrganizationNode );

Das hilft in den meisten Fällen. Was ist aber, wenn die Länge nicht noch kleiner gewählt werden kann?

In der Adventure Works DB gibt es eine Comment-Spalte unter Product Review und es gibt einen Kommentar der eine Länge von fast 4000 Zeichen hat.

select column_name, data_type, data_length, char_length from dba_tab_cols
where owner='PRODUCTION_ADVENTUREWORKS2019'
and table_name = 'PRODUCTREVIEW'
and column_name = 'COMMENTS';
COLUMN_NAME DATA_TYPE DATA_LENGTH CHAR_LENGTH
COMMENTS NVARCHAR2 7700 3850
select 'COMMENTS'
, max ( length ( COMMENTS ) ) mx_char_length
, max ( lengthb ( COMMENTS ) ) mx_byte_length
from PRODUCTION_ADVENTUREWORKS2019.PRODUCTREVIEW;
'COMMENTS MX_CHAR_LENGTH MX_BYTE_LENGTH
COMMENTS 3812 7624

Ohne Datenverlust können wir die maximale Länge nicht reduzieren. Was bleibt uns übrig?

  • Möglichkeit 1: Wir erstellen eine Datenbank mit einer größeren Datenblockgröße (db_block_size). Da wir aber schon kurz vor Abschluss der Migration sind, würden wir diese Option ungerne wählen.
  • Möglichkeit 2: Verwendung eines Tablespace mit einer Nicht-Standard Blockgröße und Anlegen des Index in diesem Tablespace. Dazu muss man aber auch den db_16k_cache_size Parameter ändern.

Führen wir folgenden Befehl in der CDB$ROOT aus

alter system set db_16k_cache_size=64M;

Anschließend in der PDB

CREATE TABLESPACE INDEX_16K DATAFILE '/data/ODB01PR/F63B0B4F4CF62086E053A80611ACEF16/datafile/INDEX_16K.dbf' size 20M blocksize 16k;

Damit der User diesen Tablespace für den Index verwenden kann, benötigt er entsprechenden Platz (Quota) im Tablespace:

ALTER USER PRODUCTION_ADVENTUREWORKS2019 QUOTA UNLIMITED ON INDEX_16K;

Anschließend kann man die Indizes unter expliziter Nennung dieses Tablespace erstellen.

CREATE INDEX IX_ProductReview_ProductID_Name ON ProductReview
(
ProductID,
ReviewerName,
Comments
) TABLESPACE INDEX_16K
;

Fazit

Wir haben in den vorhergehenden Abschnitten die MSSQL Demo Datenbank AdventureWorks von Microsoft nach Oracle migriert und die Workarounds für die Fehlermeldungen beschrieben die hierbei aufgetaucht sind.

Unsere MS SQL und Oracle Spezialisten helfen Ihnen gerne auch bei Ihrer Migration oder Fragen zur Vorgehensweise weiter! Kontaktieren Sie uns dafür gerne über unser Kontaktformular. Wir freuen uns von Ihnen zu hören!

Interesse geweckt?
Vielen Dank! Wir haben Ihre Anfrage erhalten!
Oops! Beim Senden ist etwas schiefgegangen, versuche es erneut.