---
title: "PostgreSQL zu SQL Server migrieren, im Browser"
description: "Migriere eine PostgreSQL-Datenbank zu SQL Server: 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-sql-server
last_updated: 2026-10-15
---

# PostgreSQL zu SQL Server migrieren, im Browser

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

[Leitfaden: PostgreSQL zu SQL Server migrieren](https://intosql.com/docs/migrations/postgresql-to-sql-server)

[Datentypen von PostgreSQL zu SQL Server](https://intosql.com/docs/types/postgresql-to-sql-server)

## Was sich von PostgreSQL zu SQL Server ä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 SQL Server | Berichtszeile |
| --- | --- | --- |
| boolean | bit |  |
| varchar(n), char(n), text | nvarchar(n); text als nvarchar(max) oder nvarchar(450), wenn ein Schlüssel ihn nutzt und jeder Wert passt |  |
| text comparison | exakt (Latin1_General_100_BIN2); citext ohne Groß-/Kleinschreibung (Latin1_General_100_CI_AS_SC) |  |
| numeric(p,s) past 38 digits; numeric without a precision | nvarchar; decimal(p,s) passend zu den Werten, wenn sie in 38 Stellen passen | `decimal_as_text` |
| money | decimal(19,2) | `type_replaced` |
| interval | nvarchar(100) mit dem Text von PostgreSQL | `type_replaced` |
| arrays (integer[], text[]...) | nvarchar(max) mit einem JSON-Array | `type_replaced` |
| ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types | nvarchar(max) mit dem Text von PostgreSQL | `type_replaced` |
| json, jsonb | nvarchar(max) |  |
| timestamp | datetime2 |  |
| timestamp with time zone | datetimeoffset in UTC |  |
| time with 24:00:00 in it | nvarchar(17) | `time_as_interval` |
| infinity, -infinity and BC dates | NULL | `date_out_of_range` |
| NaN and Infinity in numeric, real and double precision | NULL | `invalid_value_null` |
| NOT NULL columns with values that become NULL | NOT NULL entfernt | `not_null_relaxed` |
| enum types | nvarchar mit einem CHECK seiner Labels |  |
| enum columns holding values outside their labels | nvarchar ohne CHECK | `enum_check_skipped` |
| uuid, inet, cidr, macaddr | uniqueidentifier; Adressen als nvarchar |  |
| bytea | varbinary(max) |  |
| bit(n), bit varying | bit für ein Bit; bigint bis 63 Bit; darüber Ziffern als Text |  |
| oid, xid, cid | bigint mit einem CHECK gegen negative Werte |  |
| serial, identity | 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 ... AS bigint, mit ihrem nächsten Wert |  |
| generated columns | berechnete Spalten, PERSISTED, wenn die Quelle sie speichert |  |
| generated columns with functions SQL Server lacks | eine normale Spalte mit den Werten | `generated_not_translated` |
| defaults with functions SQL Server lacks, and defaults from a sequence | kein Standardwert | `default_not_translated` |
| CHECK constraints | übersetzt, inline in CREATE TABLE |  |
| CHECK constraints with functions SQL Server 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 text that doesn't fit a key | nicht angelegt | `index_skipped` |
| foreign keys | nach den Daten, WITH NOCHECK, dann geprüft, mit einer Warnung bei verwaisten Zeilen |  |
| ON DELETE or ON UPDATE that cascades in a cycle or along a second path | NO ACTION | `foreign_key_action_dropped` |
| foreign keys to tables the dump doesn't create | nicht angelegt | `foreign_key_skipped` |
| partitioned tables | eine Tabelle mit den Zeilen aller Partitionen | `partitions_dropped` |
| 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 | nvarchar(max) | `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 SQL Server 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
sqlcmd -b -f 65001 -S localhost -d mydb -i postgresql.sql_server.sql
```

Fremdschlüssel werden mit WITH NOCHECK hinzugefügt und dann geprüft. Verweist eine Zeile auf eine nicht vorhandene Zeile, nennt das Skript den Fremdschlüssel und lässt ihn ungeprüft, statt auf halbem Weg abzubrechen.

Führe bei einem großen Dump sqlcmd auf dem Rechner des Servers aus. Jeder Stapel von bis zu 1000 Zeilen wird einzeln festgeschrieben, so bleibt das Transaktionsprotokoll klein.

## 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 SQL Server neu schreiben kannst.

## Fragen zu PostgreSQL zu SQL Server

### 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. SQL Server zählt eine Spalte pro Tabelle, daher behält jede andere ihre Werte ohne Zähler.

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

Arrays werden JSON-Arrays, Booleans bit, uuid uniqueidentifier und Zeitstempel mit Zeitzone datetimeoffset. Text wird exakt verglichen, wie in PostgreSQL, und citext ohne Groß-/Kleinschreibung. Ranges, geometrische Typen und zusammengesetzte Typen behalten den Text von PostgreSQL.

### 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 SQL Server-Versionen lädt das Skript?

SQL Server 2017 bis 2025. Dasselbe Skript lädt auf jeder Version 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 Oracle](https://intosql.com/de/postgresql-in-oracle)

## Nach SQL Server

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

## Leitfaden und alle Paare

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