---
title: "PostgreSQL zu Oracle migrieren, im Browser"
description: "Migriere eine PostgreSQL-Datenbank zu Oracle: Eine pg_dump-Datei wird ein Skript mit denselben Tabellen, Schlüsseln und Daten, plus Bericht über jede Änderung."
canonical: https://intosql.com/de/postgresql-in-oracle
last_updated: 2026-10-15
---

# PostgreSQL zu Oracle migrieren, im Browser

Leg einen einfachen Dump aus pg_dump oder pg_dumpall ab, als .sql oder .sql.gz, und lade ein Oracle-Skript mit denselben Tabellen, Schlüsseln, Indizes und Daten herunter. Jeder Wert, den Oracle nicht unverändert aufnehmen kann, und jedes Objekt, das es nicht übernimmt, steht im Bericht.

[Leitfaden: PostgreSQL zu Oracle migrieren](https://intosql.com/docs/migrations/postgresql-to-oracle)

[Datentypen von PostgreSQL zu Oracle](https://intosql.com/docs/types/postgresql-to-oracle)

## Was sich von PostgreSQL zu Oracle ändert

Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.

| In PostgreSQL | In Oracle | Berichtszeile |
| --- | --- | --- |
| boolean | NUMBER(1) mit einem CHECK auf 0 und 1 |  |
| varchar(n), char(n) | VARCHAR2(n CHAR), in Zeichen gezählt |  |
| text | VARCHAR2(4000 CHAR), wenn jeder Wert in 4000 Bytes passt (750 Zeichen in einem Schlüssel), sonst CLOB | `text_as_lob` |
| empty strings and empty bytea values | NULL | `empty_string_null` |
| citext | exakter Vergleich | `case_insensitive_collation` |
| numeric(p,s) past 38 digits; numeric without a precision | NUMBER, wenn seine Werte in 38 Stellen passen, sonst VARCHAR2 | `decimal_as_text` |
| money | NUMBER(19,2) | `type_replaced` |
| interval | VARCHAR2(100 CHAR) mit dem Text von PostgreSQL | `type_replaced` |
| arrays (integer[], text[]...) | CLOB mit einem JSON-Array | `type_replaced` |
| ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types | VARCHAR2 oder CLOB mit dem Text von PostgreSQL | `type_replaced` |
| json, jsonb | CLOB |  |
| timestamp | TIMESTAMP |  |
| timestamp with time zone | TIMESTAMP WITH TIME ZONE in UTC |  |
| time | INTERVAL DAY TO SECOND ab Mitternacht |  |
| infinity, -infinity, BC dates and years past 9999 | NULL | `date_out_of_range` |
| NaN and Infinity in numeric | NULL | `invalid_value_null` |
| NOT NULL columns with values that become NULL | NOT NULL entfernt | `not_null_relaxed` |
| enum types | VARCHAR2 mit einem CHECK seiner Labels |  |
| enum columns holding values outside their labels | VARCHAR2 ohne CHECK | `enum_check_skipped` |
| uuid, inet, cidr, macaddr | VARCHAR2 |  |
| bytea | BLOB |  |
| bit(n), bit varying | NUMBER mit dem Wert der Bits bis 63 Bit; darüber Ziffern als Text |  |
| oid, xid, cid | NUMBER(10) mit einem CHECK gegen negative Werte |  |
| serial, identity | GENERATED BY DEFAULT ON NULL AS IDENTITY, weiter nach der höchsten ID |  |
| a second serial or identity column in a table | eine normale Ganzzahl | `counter_dropped` |
| sequences not owned by a column | CREATE SEQUENCE, bei dem Wert, den sie erreicht hatte |  |
| generated columns | virtuelle Spalten | `stored_as_virtual` |
| generated columns with functions Oracle lacks | eine normale Spalte mit den Werten | `generated_not_translated` |
| defaults with functions Oracle lacks, and defaults from a sequence | kein Standardwert | `default_not_translated` |
| CHECK constraints | übersetzt, inline in CREATE TABLE |  |
| CHECK constraints with functions Oracle lacks | nicht angelegt | `check_skipped` |
| CHECK ... NOT VALID | nicht angelegt | `check_not_valid` |
| gin, gist, brin and hash indexes, partial and expression indexes, and indexes on CLOB columns | nicht angelegt | `index_skipped` |
| foreign keys | nach den Daten, ENABLE NOVALIDATE, dann validiert, mit einer Warnung bei verwaisten Zeilen |  |
| ON UPDATE CASCADE, SET NULL or SET DEFAULT; ON DELETE SET DEFAULT | entfernt | `foreign_key_action_unsupported` |
| foreign keys to tables the dump doesn't create | nicht angelegt | `foreign_key_skipped` |
| names over 128 bytes | gekürzt | `name_shortened` |
| partitioned tables | eine Tabelle mit den Zeilen aller Partitionen | `partitions_dropped` |
| schemas | ein Schema, jede Tabelle mit dem Namen ihres Schemas vorangestellt | `schemas_merged` |
| views, functions, procedures, triggers, rules, policies, extensions and types | im Bericht aufgeführt | `not_converted_objects` |
| dumps without CREATE TABLE (--data-only) | Typen aus den Werten gelesen | `no_schema` |
| expressions in INSERT values | NULL | `expression_value` |
| types IntoSQL doesn't know | CLOB | `unknown_type` |
| text that isn't valid in its encoding | die fehlerhaften Bytes als Ersatzzeichen | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | unverändert kopiert | `mojibake_suspected` |

## Das Skript in Oracle laden

Das Skript legt die Tabellen an, kopiert die Zeilen und fügt dann Schlüssel, Indizes und Fremdschlüssel hinzu, so lädt es schnell und hält beim ersten Fehler an.

```shell
NLS_LANG=.AL32UTF8 sqlplus -S -L user@//localhost/mydb @postgresql.oracle.sql
```

Fremdschlüssel werden mit ENABLE NOVALIDATE hinzugefügt, sodass neue Zeilen sofort geprüft werden, und dann validiert. Verweist eine alte Zeile auf eine nicht vorhandene Zeile, nennt das Skript den Fremdschlüssel und lässt ihn unvalidiert, statt auf halbem Weg abzubrechen.

Führe bei einem großen Dump SQL*Plus auf dem Rechner der Datenbank aus. Das Skript schreibt alle 100 Zeilen fest. Der ausführende Benutzer braucht CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER und CREATE PROCEDURE sowie Quota auf seinem Tablespace.

## Den PostgreSQL-Dump für das beste Ergebnis erstellen

Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:

- --format=plain, die Standardeinstellung von pg_dump, schreibt SQL. Ein custom- oder directory-Archiv (-Fc, -Fd) wird mit pg_restore -f dump.sql zu SQL, ohne Datenbankserver.
- --no-owner --no-privileges lassen Rollen und Rechte weg, die der Konverter ohnehin überspringt, daher wird der Dump kleiner.
- pg_dumpall schreibt jede Datenbank in eine Datei; die Tabellen jeder Datenbank werden nach ihr benannt, damit nichts kollidiert.

## Was nicht konvertiert wird

Sichten, materialisierte Sichten, Funktionen, Prozeduren, Trigger, Regeln, Zeilensicherheitsrichtlinien, Erweiterungen und Typen sind in der eigenen Sprache von PostgreSQL geschrieben. Sie stehen mit Namen im Bericht und werden nie stillschweigend weggelassen, damit du sie für Oracle neu schreiben kannst.

## Fragen zu PostgreSQL zu Oracle

### Wird mein Dump hochgeladen?

Nein. Der Konverter läuft in deinem Browser und liest den Dump stückweise von deiner Festplatte, daher verlässt er nie deinen Computer. Die Desktop-App und die Kommandozeile konvertieren ebenfalls auf deinem Computer.

### Wie groß darf der Dump sein?

Der Konverter hält nie den ganzen Dump im Speicher: Er liest die Datei zweimal, in Abschnitten, und schreibt das Skript fortlaufend. Dumps von mehreren Gigabyte werden im Browser, in der Desktop-App und mit der Kommandozeile konvertiert.

### Liest es pg_dump -Fc-Archive?

Nicht direkt: Ein custom-Archiv ist ein Binärformat. pg_restore -f dump.sql dump.backup wandelt es in das einfache SQL um, das der Konverter liest, ohne Verbindung zu einem Server. Der Konverter sagt das, wenn er ein Archiv bekommt.

### Aus welchen PostgreSQL-Versionen kann der Dump stammen?

Dumps aus pg_dump und pg_dumpall ab PostgreSQL 10, mit COPY- oder INSERT-Zeilen. Jeder Test-Dump stammt aus PostgreSQL 13 und 18 und wird Zelle für Zelle mit seiner Quelle verglichen.

### Bleiben serial- und Identity-Werte erhalten?

Ja. Die serial- oder Identity-Spalte jeder Tabelle wird eine Identity-Spalte, jede Zeile behält ihre ID, und die nächste ID macht nach der höchsten weiter. Sequenzen, die keiner Spalte gehören, werden Oracle-Sequenzen bei dem Wert, den sie erreicht hatten.

### Was passiert mit Arrays, enums und anderen PostgreSQL-Typen?

Arrays werden JSON-Arrays, Booleans NUMBER(1), Zeitstempel mit Zeitzone TIMESTAMP WITH TIME ZONE und Text VARCHAR2, wenn seine Werte passen, sonst CLOB. Leere Strings werden NULL, wie Oracle sie speichert, und der Bericht zählt sie.

### Was ist mit Funktionen, Triggern und Sichten?

Sie stehen mit Namen im Bericht und werden nicht konvertiert, weil jede Datenbank sie in ihrer eigenen Sprache schreibt.

### Auf welchen Oracle-Versionen lädt das Skript?

Oracle 19c und neuer. Jeder Test-Dump lädt auf 21c und 23ai und hält beim ersten Fehler an, falls etwas schiefgeht.

## Aus PostgreSQL

- [PostgreSQL zu PostgreSQL](https://intosql.com/de/postgresql-in-postgresql)
- [PostgreSQL zu MySQL](https://intosql.com/de/postgresql-in-mysql)
- [PostgreSQL zu MariaDB](https://intosql.com/de/postgresql-in-mariadb)
- [PostgreSQL zu SQLite](https://intosql.com/de/postgresql-in-sqlite)
- [PostgreSQL zu SQL Server](https://intosql.com/de/postgresql-in-sql-server)

## Nach Oracle

- [MySQL zu Oracle](https://intosql.com/de/mysql-in-oracle)
- [MariaDB zu Oracle](https://intosql.com/de/mariadb-in-oracle)
- [SQL Server zu Oracle](https://intosql.com/de/sql-server-in-oracle)
- [SQLite zu Oracle](https://intosql.com/de/sqlite-in-oracle)
- [Oracle zu Oracle](https://intosql.com/de/oracle-in-oracle)

## Leitfaden und alle Paare

- [Oracle zu PostgreSQL](https://intosql.com/de/oracle-in-postgresql)
- [Leitfaden: PostgreSQL zu Oracle migrieren](https://intosql.com/docs/migrations/postgresql-to-oracle)
- [Datentypen von PostgreSQL zu Oracle](https://intosql.com/docs/types/postgresql-to-oracle)
- [Alle Datenbankpaare](https://intosql.com/de/datenbankmigration)
