---
title: "Migrer une base PostgreSQL vers SQL Server"
description: "Migrez une base PostgreSQL vers SQL Server : convertissez un fichier pg_dump en script avec les mêmes tables, clés et données, et un rapport de chaque changement."
canonical: https://intosql.com/fr/postgresql-en-sql-server
last_updated: 2026-10-15
---

# Migrer une base PostgreSQL vers SQL Server

Déposez un dump texte de pg_dump ou pg_dumpall, en .sql ou .sql.gz, et téléchargez un script SQL Server avec les mêmes tables, clés, index et données. Chaque valeur que SQL Server ne peut pas contenir telle quelle, et chaque objet qu'il ne reprend pas, est listé dans le rapport.

[Guide de migration de PostgreSQL vers SQL Server](https://intosql.com/docs/migrations/postgresql-to-sql-server)

[Types de données de PostgreSQL vers SQL Server](https://intosql.com/docs/types/postgresql-to-sql-server)

## Ce qui change de PostgreSQL à SQL Server

Chaque ligne est une règle appliquée par le convertisseur, avec la ligne de rapport qu'il écrit quand la règle change quelque chose dans vos données.

| Dans PostgreSQL | Dans SQL Server | Ligne du rapport |
| --- | --- | --- |
| boolean | bit |  |
| varchar(n), char(n), text | nvarchar(n) ; text en nvarchar(max), ou nvarchar(450) si une clé l'utilise et que chaque valeur y tient |  |
| text comparison | exacte (Latin1_General_100_BIN2) ; citext insensible à la casse (Latin1_General_100_CI_AS_SC) |  |
| numeric(p,s) past 38 digits; numeric without a precision | nvarchar ; decimal(p,s) ajusté aux valeurs si elles tiennent en 38 chiffres | `decimal_as_text` |
| money | decimal(19,2) | `type_replaced` |
| interval | nvarchar(100) avec le texte de PostgreSQL | `type_replaced` |
| arrays (integer[], text[]...) | nvarchar(max) avec un tableau JSON | `type_replaced` |
| ranges, geometric types, tsvector, xml, hstore, PostGIS, composite and extension types | nvarchar(max) avec le texte de PostgreSQL | `type_replaced` |
| json, jsonb | nvarchar(max) |  |
| timestamp | datetime2 |  |
| timestamp with time zone | datetimeoffset en 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 retiré | `not_null_relaxed` |
| enum types | nvarchar avec un CHECK de ses libellés |  |
| enum columns holding values outside their labels | nvarchar sans CHECK | `enum_check_skipped` |
| uuid, inet, cidr, macaddr | uniqueidentifier ; adresses en nvarchar |  |
| bytea | varbinary(max) |  |
| bit(n), bit varying | bit pour un seul bit ; bigint jusqu'à 63 bits ; chiffres en texte au-delà |  |
| oid, xid, cid | bigint avec un CHECK qui interdit les négatifs |  |
| serial, identity | IDENTITY, qui reprend après l'identifiant le plus élevé |  |
| a second serial or identity column in a table | un entier simple | `counter_dropped` |
| sequences not owned by a column | CREATE SEQUENCE ... AS bigint, avec sa prochaine valeur |  |
| generated columns | colonnes calculées, PERSISTED quand la source les stocke |  |
| generated columns with functions SQL Server lacks | une colonne simple avec les valeurs | `generated_not_translated` |
| defaults with functions SQL Server lacks, and defaults from a sequence | aucune valeur par défaut | `default_not_translated` |
| CHECK constraints | traduites, en ligne dans CREATE TABLE |  |
| CHECK constraints with functions SQL Server lacks | non créée | `check_skipped` |
| CHECK ... NOT VALID | non créée | `check_not_valid` |
| gin, gist, brin and hash indexes, partial and expression indexes, and indexes on text that doesn't fit a key | non créé | `index_skipped` |
| foreign keys | après les données WITH NOCHECK, puis vérifiée avec un avertissement sur les orphelins |  |
| 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 | non créée | `foreign_key_skipped` |
| partitioned tables | une seule table avec les lignes de chaque partition | `partitions_dropped` |
| views, functions, procedures, triggers, rules, policies, extensions and types | listés dans le rapport | `not_converted_objects` |
| dumps without CREATE TABLE (--data-only) | types déduits des valeurs | `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 | les octets invalides deviennent le caractère de remplacement | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | copié tel quel | `mojibake_suspected` |

## Charger le script dans SQL Server

Le script crée les tables, copie les lignes, puis ajoute les clés, les index et les clés étrangères ; il se charge donc vite et s'arrête à la première erreur.

```shell
sqlcmd -b -f 65001 -S localhost -d mydb -i postgresql.sql_server.sql
```

Les clés étrangères sont ajoutées WITH NOCHECK, puis vérifiées. Si une ligne pointe vers une ligne qui n'existe pas, le script indique quelle contrainte et la laisse non vérifiée, au lieu d'échouer à mi-chemin.

Pour un gros dump, exécutez sqlcmd sur la machine du serveur. Chaque lot de 1000 lignes au plus est validé à part, donc le journal des transactions reste petit.

## Faire le dump PostgreSQL pour un meilleur résultat

Le convertisseur lit ce que contient le dump. Ces options y gardent davantage de vos données :

- --format=plain, le format par défaut de pg_dump, écrit du SQL. Une archive custom ou directory (-Fc, -Fd) devient du SQL avec pg_restore -f dump.sql, sans serveur de base de données.
- --no-owner --no-privileges omettent les rôles et les droits, que le convertisseur ignore de toute façon ; le dump est donc plus petit.
- pg_dumpall met toutes les bases de données dans un seul fichier ; les tables de chacune sont préfixées par son nom, donc rien n'entre en collision.

## Ce qui n'est pas converti

Les vues, vues matérialisées, fonctions, procédures, déclencheurs, règles, politiques de sécurité des lignes, extensions et types sont écrits dans le langage propre à PostgreSQL. Ils sont listés par nom dans le rapport, jamais supprimés en silence, pour que vous puissiez les réécrire pour SQL Server.

## Questions sur PostgreSQL vers SQL Server

### Mon dump est-il envoyé ?

Non. Le convertisseur s'exécute dans votre navigateur et lit le dump depuis votre disque par morceaux ; il ne quitte donc jamais votre ordinateur. L'application de bureau et la ligne de commande convertissent aussi sur votre ordinateur.

### Quelle taille peut avoir le dump ?

Le convertisseur ne garde jamais tout le dump en mémoire : il lit le fichier deux fois, par plages, et écrit le script au fur et à mesure. Les dumps de plusieurs gigaoctets se convertissent dans le navigateur, dans l'application de bureau et avec la ligne de commande.

### Lit-il les archives pg_dump -Fc ?

Pas directement : une archive custom est un format binaire. pg_restore -f dump.sql dump.backup la transforme en SQL texte que le convertisseur lit, sans se connecter à un serveur. Le convertisseur le signale quand il reçoit une archive.

### De quelles versions de PostgreSQL le dump peut-il venir ?

Les dumps écrits par pg_dump et pg_dumpall depuis PostgreSQL 10, avec des lignes COPY ou INSERT. Chaque dump de test vient de PostgreSQL 13 et 18 et est comparé à sa source cellule par cellule.

### Les valeurs serial et identity sont-elles conservées ?

Oui. La colonne serial ou identity de chaque table devient une colonne IDENTITY, chaque ligne garde son identifiant, et le prochain identifiant reprend après le plus élevé. SQL Server compte une colonne par table ; toute autre garde donc ses valeurs sans compteur.

### Que deviennent les tableaux, les enums et les autres types PostgreSQL ?

Les tableaux deviennent des tableaux JSON, les booléens bit, uuid uniqueidentifier, et les timestamps avec fuseau horaire datetimeoffset. Le texte se compare exactement, comme dans PostgreSQL, et citext sans tenir compte de la casse. Les plages, types géométriques et types composites gardent le texte de PostgreSQL.

### Et les fonctions, les déclencheurs et les vues ?

Ils sont listés par nom dans le rapport et ne sont pas convertis, car chaque base de données les écrit dans son propre langage.

### Sur quelles versions de SQL Server le script se charge-t-il ?

SQL Server 2017 à 2025. Le même script se charge sur chacune, et s'arrête à la première erreur en cas de problème.

## Depuis PostgreSQL

- [PostgreSQL vers PostgreSQL](https://intosql.com/fr/postgresql-en-postgresql)
- [PostgreSQL vers MySQL](https://intosql.com/fr/postgresql-en-mysql)
- [PostgreSQL vers MariaDB](https://intosql.com/fr/postgresql-en-mariadb)
- [PostgreSQL vers SQLite](https://intosql.com/fr/postgresql-en-sqlite)
- [PostgreSQL vers Oracle](https://intosql.com/fr/postgresql-en-oracle)

## Vers SQL Server

- [MySQL vers SQL Server](https://intosql.com/fr/mysql-en-sql-server)
- [MariaDB vers SQL Server](https://intosql.com/fr/mariadb-en-sql-server)
- [SQL Server vers SQL Server](https://intosql.com/fr/sql-server-en-sql-server)
- [SQLite vers SQL Server](https://intosql.com/fr/sqlite-en-sql-server)
- [Oracle vers SQL Server](https://intosql.com/fr/oracle-en-sql-server)

## Guide et toutes les paires

- [SQL Server vers PostgreSQL](https://intosql.com/fr/sql-server-en-postgresql)
- [Guide de migration de PostgreSQL vers SQL Server](https://intosql.com/docs/migrations/postgresql-to-sql-server)
- [Types de données de PostgreSQL vers SQL Server](https://intosql.com/docs/types/postgresql-to-sql-server)
- [Toutes les paires de bases de données](https://intosql.com/fr/migration-de-base-de-donnees)
