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

# Migrer une base MySQL vers SQL Server

Déposez un dump de mysqldump, mariadb-dump, mysqlpump, phpMyAdmin ou Adminer, 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 MySQL vers SQL Server](https://intosql.com/docs/migrations/mysql-to-sql-server)

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

## Ce qui change de MySQL à 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 MySQL | Dans SQL Server | Ligne du rapport |
| --- | --- | --- |
| TINYINT(1), BOOL | bit si chaque valeur vaut 0 ou 1, sinon smallint | `bool_kept_numeric` |
| UNSIGNED integers | TINYINT UNSIGNED devient tinyint ; les autres, l'entier immédiatement plus large avec un CHECK qui interdit les négatifs, BIGINT UNSIGNED devient bigint si chaque valeur y tient, sinon decimal(38,0) | `unsigned_widened` |
| ZEROFILL and display widths | supprimé | `zerofill_dropped` |
| FLOAT(M,D) | real ou float, sans l'échelle | `float_scale_dropped` |
| DECIMAL(p,s) | decimal(p,s) jusqu'à 38 chiffres ; nvarchar au-delà | `decimal_as_text` |
| BIT(1), BIT(n) | bit ; bigint jusqu'à 63 bits ; decimal(20,0) pour BIT(64) |  |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULL | `invalid_date_null` |
| NOT NULL columns with values that become NULL | NOT NULL retiré | `not_null_relaxed` |
| DEFAULT '0000-00-00' | aucune valeur par défaut | `zero_date_default` |
| TIME | time si chaque valeur tient dans une journée, sinon nvarchar | `time_as_interval` |
| YEAR | smallint avec un CHECK de sa plage |  |
| CHAR(n), VARCHAR(n) | nvarchar(n) |  |
| text with characters past U+FFFF (emoji) in VARCHAR(n) | nvarchar(2n), ou nvarchar(max) au-delà de 4000 | `text_length_widened` |
| DATETIME | datetime2 |  |
| TIMESTAMP | datetimeoffset dans le fuseau horaire indiqué par le dump, UTC s'il n'en indique aucun | `timestamp_zone_assumed` |
| ENUM | nvarchar avec un CHECK de ses valeurs |  |
| ENUM holding '' (MySQL's error value) | la valeur vide autorisée par le CHECK | `enum_invalid_value` |
| ENUM holding values outside its list | pas de CHECK | `enum_check_skipped` |
| SET | nvarchar tel que MySQL l'écrit ('a,b') |  |
| JSON | nvarchar(max) |  |
| NUL bytes in text | conservé |  |
| text that isn't valid in its character set | les octets invalides deviennent le caractère de remplacement | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | copié tel quel | `mojibake_suspected` |
| AUTO_INCREMENT | IDENTITY, avec le compteur placé après les identifiants copiés |  |
| MyISAM AUTO_INCREMENT on the second column of a key | un seul compteur pour la table | `myisam_group_autoincrement` |
| ON UPDATE CURRENT_TIMESTAMP | un déclencheur AFTER UPDATE | `on_update_trigger` |
| ON UPDATE CURRENT_TIMESTAMP on a table without a primary key | non reporté | `on_update_without_key` |
| generated columns | colonnes calculées, PERSISTED quand la source les stocke |  |
| generated columns with functions SQL Server lacks | une colonne simple | `generated_not_translated` |
| INVISIBLE columns | colonnes ordinaires | `invisible_column` |
| CHECK constraints | traduites, en ligne dans CREATE TABLE |  |
| CHECK constraints with functions SQL Server lacks | non créée | `check_skipped` |
| CHECK ... NOT ENFORCED | non créée | `check_not_enforced` |
| defaults with functions SQL Server lacks | aucune valeur par défaut | `default_not_translated` |
| keys and indexes on a prefix, c(20) | un index sur la colonne entière | `prefix_whole_column` |
| FULLTEXT indexes | non créée | `fulltext_not_created` |
| SPATIAL indexes | non créée | `spatial_index_not_created` |
| functional indexes, and indexes on columns of unlimited length | 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 columns without a unique key | non créée | `foreign_key_skipped` |
| table and column names | tels qu'écrits ; renommés s'ils ne diffèrent que par la casse | `identifier_renamed` |
| names over 116 characters | raccourci | `name_shortened` |
| GEOMETRY, POINT, POLYGON... | geometry, avec le SRID de chaque valeur |  |
| INET4, INET6, UUID (MariaDB) | nvarchar(39), uniqueidentifier |  |
| BINARY, VARBINARY, BLOB | binary, varbinary, varbinary(max) |  |
| PARTITION BY | une seule table | `partitions_dropped` |
| WITH SYSTEM VERSIONING (MariaDB) | une table avec les lignes actuelles | `system_versioning_dropped` |
| MyISAM, MEMORY and other engines | une table ordinaire | `engine_dropped` |
| views, triggers, procedures, functions and events | listés dans le rapport | `not_converted_objects` |
| dumps without CREATE TABLE | types déduits des valeurs | `no_schema` |
| geometries in a dump without CREATE TABLE | geometry |  |
| _ci collations | la collation de la base, en général insensible à la casse |  |
| SET NAMES utf8 from utf8mb4 tables | converti, avec un avertissement | `dump_lost_four_byte_chars` |
| dumps without SET NAMES whose text isn't UTF-8 | lu comme Latin-1 (Windows-1252) | `charset_guessed` |
| sjis, cp932, gbk, big5 dumps | lu comme UTF-8, avec un avertissement | `unsupported_charset` |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | évaluées |  |
| other expressions in rows | NULL | `expression_value` |
| DEFAULT in VALUES | la valeur par défaut de la colonne | `default_keyword_filled` |
| DEFAULT in VALUES without a literal default | NULL | `default_keyword_null` |
| REPLACE and INSERT IGNORE | lignes simples | `replace_as_insert` |
| types IntoSQL doesn't know | nvarchar(max) | `unknown_type` |
| values that don't fit their column | NULL | `invalid_value_null` |
| unreadable geometries | NULL | `bad_geometry` |
| CREATE SEQUENCE (MariaDB) | CREATE SEQUENCE ... AS bigint, avec sa prochaine valeur |  |
| VECTOR(n) (MariaDB 11.7+) | nvarchar(max) avec les flottants en tableau JSON | `type_replaced` |

## 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 mysql.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 MySQL pour un meilleur résultat

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

- --default-character-set=utf8mb4 garde les emoji et autres caractères sur 4 octets, qu'un dump utf8 perd avant que le convertisseur ne le voie.
- --hex-blob écrit les colonnes binaires en hexadécimal, ce qui résiste aux copies entre systèmes.
- --routines --triggers --events ajoutent ces objets au dump, pour que le rapport puisse les lister.

## Ce qui n'est pas converti

Les vues, déclencheurs, procédures stockées, fonctions et événements sont écrits dans le langage propre à chaque base de données. 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 MySQL 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 dumps MariaDB ?

Oui. Les dumps de mariadb-dump et de MariaDB 10.3 à 12 se convertissent de la même façon, y compris les colonnes INET6, INET4 et UUID de MariaDB.

### Que deviennent les dates 0000-00-00 ?

SQL Server n'a pas de date zéro ; elles deviennent donc NULL et la colonne accepte NULL. Le rapport indique combien il y en avait dans chaque colonne.

### Les valeurs AUTO_INCREMENT sont-elles conservées ?

Oui. Chaque colonne AUTO_INCREMENT devient une colonne IDENTITY, chaque ligne garde son identifiant, et le prochain identifiant reprend après le plus élevé, ou après l'AUTO_INCREMENT de la table s'il est plus grand.

### TINYINT(1) devient-il boolean ?

Elle devient bit seulement si chaque valeur de la colonne vaut 0 ou 1. Si elle contient d'autres nombres, comme 2 ou -1, elle reste un nombre et le rapport explique pourquoi ; aucune valeur ne devient 1 par accident.

### Et les procédures stockées et les déclencheurs ?

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. ON UPDATE CURRENT_TIMESTAMP est l'exception : il devient un déclencheur SQL Server.

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

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

## Vers SQL Server

- [MariaDB vers SQL Server](https://intosql.com/fr/mariadb-en-sql-server)
- [PostgreSQL vers SQL Server](https://intosql.com/fr/postgresql-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 MySQL](https://intosql.com/fr/sql-server-en-mysql)
- [Guide de migration de MySQL vers SQL Server](https://intosql.com/docs/migrations/mysql-to-sql-server)
- [Types de données de MySQL vers SQL Server](https://intosql.com/docs/types/mysql-to-sql-server)
- [Toutes les paires de bases de données](https://intosql.com/fr/migration-de-base-de-donnees)
