Aller au contenu
Accueil IntoSQL

Convertir MySQL en 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.

Votre fichier
sqlshop_2024.sqlFichier d'exemple, 5,1 ko
Votre base de données

18 lignes converties, 10 corrections, aucune rejetée

Afficher

Tables de shop_2024.sqlDump MySQL 8.0.46 · écrit par mysqldump · utf8mb4

  • customers8 lignes4
    7 colonnes
    idbigint not null
    namenvarchar(200) not null
    emailnvarchar(150) not null
    countrynvarchar(2) not null
    is_activebit not null
    signed_update
    created_atdatetimeoffset(0) not null
  • orders10 lignes6
    9 colonnes
    idbigint not null
    customer_idbigint not null
    statusnvarchar(9) not null
    totaldecimal(10,2) not null
    itemsint not null
    ordered_atdatetime2(0) not null
    shipped_atdatetime2(0)
    notenvarchar(510)
    updated_atdatetimeoffset(0) not null
-- Written by IntoSQL from a MySQL dump. Load it with: sqlcmd -b -f 65001 -d <database> -i <file>
SET NOCOUNT ON;
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET NUMERIC_ROUNDABORT OFF;
GO

CREATE TABLE [dbo].[customers] (
    [id] bigint IDENTITY(1001, 1) NOT NULL,
    [name] nvarchar(200) NOT NULL,
    [email] nvarchar(150) NOT NULL,
    [country] nvarchar(2) DEFAULT N'US' NOT NULL,
    [is_active] bit DEFAULT 1 NOT NULL,
    [signed_up] date NULL,
    [created_at] datetimeoffset(0) DEFAULT SYSDATETIMEOFFSET() NOT NULL,
    CONSTRAINT [CK_customers_id] CHECK ([id] >= 0),
    CONSTRAINT [PK_customers] PRIMARY KEY ([id])
);
GO

CREATE TABLE [dbo].[orders] (
    [id] bigint IDENTITY(5001, 1) NOT NULL,
    [customer_id] bigint NOT NULL,
    [status] nvarchar(9) DEFAULT N'pending' NOT NULL,
    [total] decimal(10,2) NOT NULL,
    [items] int DEFAULT 1 NOT NULL,
    [ordered_at] datetime2(0) NOT NULL,
    [shipped_at] datetime2(0) NULL,
    [note] nvarchar(510) NULL,
    [updated_at] datetimeoffset(0) DEFAULT SYSDATETIMEOFFSET() NOT NULL,
    CONSTRAINT [CK_orders_id] CHECK ([id] >= 0),
    CONSTRAINT [CK_orders_customer_id] CHECK ([customer_id] >= 0),
    CONSTRAINT [CK_orders_status] CHECK ([status] IN (N'pending', N'paid', N'shipped', N'cancelled', N'')),
    CONSTRAINT [CK_orders_items] CHECK ([items] >= 0),
    CONSTRAINT [PK_orders] PRIMARY KEY ([id])
);
GO

SET IDENTITY_INSERT [dbo].[customers] ON;
INSERT INTO [dbo].[customers] ([id], [name], [email], [country], [is_active], [signed_up], [created_at]) VALUES
(1,N'Ana Martínez',N'ana@example.com',N'MX',1,'2023-01-15','2023-01-15 10:24:00+00:00'),
(2,N'Zoë Müller',N'zoe@example.de',N'DE',1,'2023-02-03','2023-02-03 08:11:42+00:00'),
(3,N'José Peña',N'jose@example.es',N'ES',0,'2023-03-21','2023-03-21 19:05:17+00:00'),
(4,N'李雷',N'lilei@example.cn',N'CN',1,'2023-05-09','2023-05-09 02:40:00+00:00'),
(5,N'Noah O''Brien',N'noah@example.ie',N'IE',1,NULL,'2023-06-30 14:00:00+00:00'),
(6,N'Amélie Laurent',N'amelie@example.fr',N'FR',1,'2024-01-02','2024-01-02 09:30:00+00:00'),
(7,N'Ravi Patel',N'ravi@example.in',N'IN',0,'2024-02-29','2024-02-29 23:59:59+00:00'),
(8,N'Sofia Rossi 🌻',N'sofia@example.it',N'IT',1,'2024-04-12','2024-04-12 12:12:12+00:00');
SET IDENTITY_INSERT [dbo].[customers] OFF;
GO
SET IDENTITY_INSERT [dbo].[orders] ON;
INSERT INTO [dbo].[orders] ([id], [customer_id], [status], [total], [items], [ordered_at], [shipped_at], [note], [updated_at]) VALUES
(1,1,N'shipped',129.90,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,'2024-03-02 16:30:00+00:00'),
(2,2,N'paid',54.00,1,'2024-03-02 11:15:00',NULL,N'Gift wrap 🎁','2024-03-02 11:20:00+00:00'),
(3,1,N'cancelled',12.50,1,'2024-03-03 09:45:00',NULL,N'Customer changed their mind','2024-03-03 10:00:00+00:00'),
(4,4,N'shipped',980.00,12,'2024-03-05 02:10:00','2024-03-07 08:00:00',N'请小心轻放','2024-03-07 08:00:00+00:00'),
(5,5,N'pending',45.75,2,'2024-03-08 17:20:00',NULL,N'Leave at the door; ring twice','2024-03-08 17:20:00+00:00'),
(6,6,N'shipped',310.40,5,'2024-03-10 13:00:00','2024-03-11 09:00:00',N'Fragile: "glass"','2024-03-11 09:00:00+00:00'),
(7,8,N'paid',76.20,2,'2024-03-11 18:45:00',NULL,NULL,'2024-03-11 18:46:00+00:00'),
(8,2,N'',19.99,1,'2024-03-12 08:00:00',NULL,N'Status lost in an old import','2024-03-12 08:00:00+00:00'),
(9,3,N'shipped',64.00,2,'2024-03-14 15:30:00',NULL,N'Shipping date never recorded','2024-03-15 10:00:00+00:00'),
(10,7,N'paid',1499.00,1,'2024-03-15 21:05:00',NULL,N'C:\Users\ravi\invoice.pdf','2024-03-15 21:05:00+00:00');
SET IDENTITY_INSERT [dbo].[orders] OFF;
GO

-- Indexes, foreign keys, counters and triggers, after the rows.
CREATE UNIQUE INDEX [uq_email] ON [dbo].[customers] ([email]);
CREATE INDEX [idx_customer] ON [dbo].[orders] ([customer_id]);
CREATE INDEX [idx_status_date] ON [dbo].[orders] ([status], [ordered_at]);
ALTER TABLE [dbo].[orders] WITH NOCHECK ADD CONSTRAINT [fk_orders_customer] FOREIGN KEY ([customer_id]) REFERENCES [dbo].[customers] ([id]);
BEGIN TRY ALTER TABLE [dbo].[orders] WITH CHECK CHECK CONSTRAINT [fk_orders_customer]; END TRY BEGIN CATCH PRINT N'Foreign key ' + N'[fk_orders_customer]' + N' has rows without a parent: it stays unchecked, and new rows are checked.'; END CATCH;
DECLARE @next decimal(38,0) = (SELECT MAX([id]) FROM [dbo].[customers]); IF @next IS NOT NULL BEGIN IF @next < 1000 SET @next = 1000; DBCC CHECKIDENT (N'[dbo].[customers]', RESEED, @next) WITH NO_INFOMSGS; END;
GO
EXEC sys.sp_addextendedproperty @name = N'MS_Description', @value = N'People who bought at least once', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'customers';
DECLARE @next decimal(38,0) = (SELECT MAX([id]) FROM [dbo].[orders]); IF @next IS NOT NULL BEGIN IF @next < 5000 SET @next = 5000; DBCC CHECKIDENT (N'[dbo].[orders]', RESEED, @next) WITH NO_INFOMSGS; END;
GO
GO
CREATE TRIGGER [dbo].[TR_orders_updated_at_on_update] ON [dbo].[orders] AFTER UPDATE AS
BEGIN
    SET NOCOUNT ON;
    IF NOT UPDATE([updated_at])
        UPDATE x SET [updated_at] = SYSDATETIMEOFFSET() FROM [dbo].[orders] AS x JOIN inserted AS i ON x.[id] = i.[id];
END;
GO
GO

Corrections

  1. "id" de customers est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
  2. "name" de customers contient des caractères que SQL Server compte double, comme les emoji ; elle est donc en nvarchar(200).
  3. "signed_up" de customers accepte maintenant NULL : certaines de ses valeurs ne pouvaient pas être stockées et sont NULL.
  4. La valeur par défaut de "signed_up" dans customers, 0000‑00‑00, n'est pas une date acceptée par SQL Server ; la colonne n'a donc pas de valeur par défaut.
  5. "customer_id" de orders est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
  6. "id" de orders est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
  7. "items" de orders est non signée ; elle est donc devenue int avec un CHECK qui interdit les valeurs négatives.
  8. "note" de orders contient des caractères que SQL Server compte double, comme les emoji ; elle est donc en nvarchar(510).
  9. 1 ligne de "status" dans orders contient la valeur vide que MySQL stocke pour les entrées invalides ; la contrainte CHECK de ses valeurs l'autorise.
  10. "updated_at" de orders passe à l'heure actuelle à chaque mise à jour ; dans SQL Server, un déclencheur s'en charge.

À vérifier

  • 1 valeur dans "signed_up" de customers est une date zéro ou impossible, comme 0000‑00‑00, que SQL Server ne peut pas stocker ; elle est donc NULL. Si ces dates ont un sens, remplacez-les dans la source par de vraies dates avant le dump.
  • 1 valeur dans "shipped_at" de orders est une date zéro ou impossible, comme 0000‑00‑00 00:00:00, que SQL Server ne peut pas stocker ; elle est donc NULL. Si ces dates ont un sens, remplacez-les dans la source par de vraies dates avant le dump.

Votre fichier est converti sur cet ordinateur et n'est jamais envoyé.

Autres exemples :

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.

  • TINYINT(1), BOOL

    bit si chaque valeur vaut 0 ou 1, sinon smallint

    Le BOOL de MySQL est un TINYINT(1) qui peut contenir tout nombre de -128 à 127. Une colonne qui ne contient que 0 et 1 devient bit ; une colonne qui contient 2 ou -1 reste un nombre, pour qu'aucune valeur ne change de sens.

    Ligne du rapport: 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)

    SQL Server n'a pas d'entiers non signés sauf tinyint, qui va de 0 à 255. Un type plus large contient toute la plage non signée, et la contrainte CHECK écarte les valeurs négatives comme le faisait MySQL.

    Ligne du rapport: unsigned_widened

  • ZEROFILL and display widths

    supprimé

    Le remplissage par des zéros est une façon d'afficher un nombre, pas une partie du nombre. Les nombres sont conservés ; formatez-les à la lecture si le remplissage compte.

    Ligne du rapport: zerofill_dropped

  • FLOAT(M,D)

    real ou float, sans l'échelle

    Les flottants SQL Server n'ont pas d'échelle fixe. Les valeurs stockées sont copiées telles quelles.

    Ligne du rapport: float_scale_dropped

  • DECIMAL(p,s)

    decimal(p,s) jusqu'à 38 chiffres ; nvarchar au-delà

    Le decimal de SQL Server contient 38 chiffres. Les décimaux plus larges sont gardés en texte pour que chaque chiffre reste exact.

    Ligne du rapport: decimal_as_text

  • BIT(1), BIT(n)

    bit ; bigint jusqu'à 63 bits ; decimal(20,0) pour BIT(64)

    Un seul bit est un oui ou un non ; les champs de bits plus larges sont stockés comme le nombre que forment leurs bits.

  • zero, partial or impossible dates (0000-00-00, 2024-02-30)

    NULL

    SQL Server ne stocke que de vraies dates du calendrier. MySQL garde les dates zéro et impossibles quand son mode SQL les autorise ; elles deviennent NULL et le rapport les compte.

    Ligne du rapport: invalid_date_null

  • NOT NULL columns with values that become NULL

    NOT NULL retiré

    Une colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait.

    Ligne du rapport: not_null_relaxed

  • DEFAULT '0000-00-00'

    aucune valeur par défaut

    Une valeur par défaut que SQL Server ne peut pas stocker est omise plutôt que remplacée par une date inventée.

    Ligne du rapport: zero_date_default

  • TIME

    time si chaque valeur tient dans une journée, sinon nvarchar

    Le TIME de MySQL est une durée de -838:59:59 à 838:59:59 ; le time de SQL Server est une heure du jour. Une colonne avec des valeurs plus longues ou négatives les garde en texte.

    Ligne du rapport: time_as_interval

  • YEAR

    smallint avec un CHECK de sa plage

    SQL Server n'a pas de type année ; le CHECK garde les mêmes valeurs que MySQL autorise.

  • CHAR(n), VARCHAR(n)

    nvarchar(n)

    nvarchar contient tous les caractères sur chaque version prise en charge, et MySQL renvoie les valeurs CHAR sans espaces de fin, telles que nvarchar les garde.

  • text with characters past U+FFFF (emoji) in VARCHAR(n)

    nvarchar(2n), ou nvarchar(max) au-delà de 4000

    nvarchar compte en unités UTF-16 et un emoji en prend deux ; la colonne a donc la place pour chaque valeur.

    Ligne du rapport: text_length_widened

  • DATETIME

    datetime2

    Un DATETIME est une date et une heure locales, sans fuseau horaire, comme datetime2.

  • TIMESTAMP

    datetimeoffset dans le fuseau horaire indiqué par le dump, UTC s'il n'en indique aucun

    Un TIMESTAMP est un instant. Les dumps indiquent le fuseau dans lequel ils l'ont écrit (mysqldump écrit en UTC) ; sinon, les valeurs sont lues en UTC et le rapport le signale.

    Ligne du rapport: timestamp_zone_assumed

  • ENUM

    nvarchar avec un CHECK de ses valeurs

    Un texte avec une contrainte CHECK garde les mêmes valeurs.

  • ENUM holding '' (MySQL's error value)

    la valeur vide autorisée par le CHECK

    MySQL stocke une chaîne vide quand une valeur invalide entre dans un ENUM avec un mode SQL permissif. Ces lignes sont conservées et la contrainte CHECK les autorise.

    Ligne du rapport: enum_invalid_value

  • ENUM holding values outside its list

    pas de CHECK

    Les valeurs absentes de la liste feraient échouer la contrainte CHECK, qui n'est donc pas créée.

    Ligne du rapport: enum_check_skipped

  • SET

    nvarchar tel que MySQL l'écrit ('a,b')

    SQL Server n'a pas de tableaux ; le texte est celui que MySQL renvoie.

  • JSON

    nvarchar(max)

    Les fonctions JSON de SQL Server lisent le JSON depuis du texte. Un CHECK ISJSON refuserait avant SQL Server 2022 des valeurs scalaires comme 1 ou "x", que MySQL garde.

  • NUL bytes in text

    conservé

    nvarchar peut contenir un caractère NUL, donc la valeur est copiée telle quelle.

  • text that isn't valid in its character set

    les octets invalides deviennent le caractère de remplacement

    Le texte doit être lu comme des caractères pour être écrit en nvarchar.

    Ligne du rapport: invalid_utf8_replaced

  • text decoded twice (ñ)

    copié tel quel

    Le dump contient exactement ces caractères, ils sont donc copiés ; le rapport les signale.

    Ligne du rapport: mojibake_suspected

  • AUTO_INCREMENT

    IDENTITY, avec le compteur placé après les identifiants copiés

    Les identifiants copiés se chargent avec IDENTITY_INSERT, et le compteur reprend après le plus élevé ou après l'AUTO_INCREMENT du dump, selon le plus grand.

  • MyISAM AUTO_INCREMENT on the second column of a key

    un seul compteur pour la table

    MyISAM compte par groupe de la première colonne de la clé ; SQL Server a un compteur par table.

    Ligne du rapport: myisam_group_autoincrement

  • ON UPDATE CURRENT_TIMESTAMP

    un déclencheur AFTER UPDATE

    Le déclencheur met la colonne à l'heure actuelle quand une mise à jour ne la définit pas. Il fait la jointure sur la clé primaire, donc la table doit en avoir une.

    Ligne du rapport: on_update_trigger

  • ON UPDATE CURRENT_TIMESTAMP on a table without a primary key

    non reporté

    Le déclencheur trouve les lignes mises à jour par leur clé primaire ; sans clé primaire, il ne peut pas.

    Ligne du rapport: on_update_without_key

  • generated columns

    colonnes calculées, PERSISTED quand la source les stocke

    SQL Server les calcule des deux mêmes façons.

  • generated columns with functions SQL Server lacks

    une colonne simple

    Une formule qui ne peut pas être écrite pour SQL Server laisse une colonne simple et une ligne dans le rapport.

    Ligne du rapport: generated_not_translated

  • INVISIBLE columns

    colonnes ordinaires

    SQL Server n'a pas de colonnes invisibles.

    Ligne du rapport: invisible_column

  • CHECK constraints

    traduites, en ligne dans CREATE TABLE

    Les CHECK en ligne sont vérifiés au chargement de chaque ligne.

  • CHECK constraints with functions SQL Server lacks

    non créée

    Une contrainte CHECK qui ne peut pas être écrite pour SQL Server est omise et signalée.

    Ligne du rapport: check_skipped

  • CHECK ... NOT ENFORCED

    non créée

    MySQL garde ces contraintes CHECK sans les appliquer, donc les lignes peuvent les enfreindre.

    Ligne du rapport: check_not_enforced

  • defaults with functions SQL Server lacks

    aucune valeur par défaut

    Une valeur par défaut qui ne peut pas être écrite pour SQL Server est omise et signalée.

    Ligne du rapport: default_not_translated

  • keys and indexes on a prefix, c(20)

    un index sur la colonne entière

    SQL Server indexe des colonnes entières ; une clé unique sur un préfixe est aussi unique sur la colonne entière, donc chaque ligne se charge.

    Ligne du rapport: prefix_whole_column

  • FULLTEXT indexes

    non créée

    La recherche plein texte de SQL Server demande un catalogue et ses propres requêtes.

    Ligne du rapport: fulltext_not_created

  • SPATIAL indexes

    non créée

    Un index spatial sur une colonne geometry demande une zone englobante que le dump n'indique pas.

    Ligne du rapport: spatial_index_not_created

  • functional indexes, and indexes on columns of unlimited length

    non créé

    SQL Server n'indexe ni les expressions ni les colonnes nvarchar(max) et varbinary(max).

    Ligne du rapport: index_skipped

  • foreign keys

    après les données WITH NOCHECK, puis vérifiée avec un avertissement sur les orphelins

    Les dumps se chargent avec FOREIGN_KEY_CHECKS=0 et MyISAM ne vérifie jamais, donc les lignes sans parent sont fréquentes. La clé est créée d'abord et vérifiée en dernier ; des orphelins la laissent non vérifiée avec un avertissement au lieu d'arrêter le chargement.

  • ON DELETE or ON UPDATE that cascades in a cycle or along a second path

    NO ACTION

    SQL Server refuse les cascades qui pourraient atteindre une table deux fois ; MySQL les autorise.

    Ligne du rapport: foreign_key_action_dropped

  • foreign keys to columns without a unique key

    non créée

    SQL Server exige une clé primaire ou un index unique sans NULL sur les colonnes référencées ; InnoDB non.

    Ligne du rapport: foreign_key_skipped

  • table and column names

    tels qu'écrits ; renommés s'ils ne diffèrent que par la casse

    Les noms SQL Server ignorent la casse avec la collation habituelle.

    Ligne du rapport: identifier_renamed

  • names over 116 characters

    raccourci

    Les noms SQL Server font 128 caractères au plus, dont certains pour les numéros qui distinguent les noms.

    Ligne du rapport: name_shortened

  • GEOMETRY, POINT, POLYGON...

    geometry, avec le SRID de chaque valeur

    Le type geometry propre à SQL Server garde chaque forme et son système de référence spatiale.

  • INET4, INET6, UUID (MariaDB)

    nvarchar(39), uniqueidentifier

    uniqueidentifier est l'UUID de SQL Server ; les adresses sont gardées en texte.

  • BINARY, VARBINARY, BLOB

    binary, varbinary, varbinary(max)

    Les octets restent des octets.

  • PARTITION BY

    une seule table

    Les lignes sont les mêmes ; partitionnez à nouveau la table dans SQL Server si besoin.

    Ligne du rapport: partitions_dropped

  • WITH SYSTEM VERSIONING (MariaDB)

    une table avec les lignes actuelles

    Un dump ne contient que les lignes actuelles.

    Ligne du rapport: system_versioning_dropped

  • MyISAM, MEMORY and other engines

    une table ordinaire

    SQL Server a un seul moteur de tables.

    Ligne du rapport: engine_dropped

  • views, triggers, procedures, functions and events

    listés dans le rapport

    Leur code est écrit dans le langage de MySQL ; ils sont donc listés pour que vous les recréiez.

    Ligne du rapport: not_converted_objects

  • dumps without CREATE TABLE

    types déduits des valeurs

    Un dump fait avec --no-create-info ne contient que des lignes, donc les types viennent des valeurs.

    Ligne du rapport: no_schema

  • geometries in a dump without CREATE TABLE

    geometry

    Le format de géométrie de MySQL est reconnu à partir des valeurs.

  • _ci collations

    la collation de la base, en général insensible à la casse

    SQL Server compare le texte sans tenir compte de la casse avec sa collation habituelle, comme le _ci de MySQL.

  • SET NAMES utf8 from utf8mb4 tables

    converti, avec un avertissement

    Le mysqldump de MySQL 5.x écrit par défaut en utf8 sur 3 octets et remplace chaque emoji par un point d'interrogation avant qu'un convertisseur ne voie le fichier.

    Ligne du rapport: dump_lost_four_byte_chars

  • dumps without SET NAMES whose text isn't UTF-8

    lu comme Latin-1 (Windows-1252)

    Le latin1 de MySQL est le Windows-1252, l'encodage habituel de ces dumps.

    Ligne du rapport: charset_guessed

  • sjis, cp932, gbk, big5 dumps

    lu comme UTF-8, avec un avertissement

    Ces encodages ne sont pas encore décodés.

    Ligne du rapport: unsupported_charset

  • UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows

    évaluées

    Certains outils de dump écrivent les valeurs sous forme de ces appels ; ils sont lus comme les valeurs qu'ils produisent, le WKT géographique étant remis avec la longitude en premier.

  • other expressions in rows

    NULL

    Un convertisseur qui n'exécute pas de base de données ne peut pas les évaluer.

    Ligne du rapport: expression_value

  • DEFAULT in VALUES

    la valeur par défaut de la colonne

    Une valeur par défaut littérale est copiée dans la ligne.

    Ligne du rapport: default_keyword_filled

  • DEFAULT in VALUES without a literal default

    NULL

    Il n'y a aucune valeur à copier.

    Ligne du rapport: default_keyword_null

  • REPLACE and INSERT IGNORE

    lignes simples

    Un dump a une ligne par clé, donc les lignes sont les mêmes.

    Ligne du rapport: replace_as_insert

  • types IntoSQL doesn't know

    nvarchar(max)

    Le texte contient n'importe quelle valeur ; changez le type après le chargement.

    Ligne du rapport: unknown_type

  • values that don't fit their column

    NULL

    Un dump endommagé ou écrit à la main peut contenir des valeurs que sa colonne n'accepte pas ; elles deviennent NULL pour que le reste se charge.

    Ligne du rapport: invalid_value_null

  • unreadable geometries

    NULL

    Des octets qui ne forment pas une géométrie ne peuvent pas être stockés comme telle.

    Ligne du rapport: bad_geometry

  • CREATE SEQUENCE (MariaDB)

    CREATE SEQUENCE ... AS bigint, avec sa prochaine valeur

    SQL Server a des séquences avec les mêmes options ; chacune reprend là où le dump l'a laissée.

  • VECTOR(n) (MariaDB 11.7+)

    nvarchar(max) avec les flottants en tableau JSON

    Seul SQL Server 2025 a un type vector ; un tableau JSON garde chaque flottant dans toutes les versions.

    Ligne du rapport: type_replaced

Dans MySQLDans SQL ServerLigne du rapport
TINYINT(1), BOOLbit si chaque valeur vaut 0 ou 1, sinon smallintLe BOOL de MySQL est un TINYINT(1) qui peut contenir tout nombre de -128 à 127. Une colonne qui ne contient que 0 et 1 devient bit ; une colonne qui contient 2 ou -1 reste un nombre, pour qu'aucune valeur ne change de sens.bool_kept_numeric
UNSIGNED integersTINYINT 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)SQL Server n'a pas d'entiers non signés sauf tinyint, qui va de 0 à 255. Un type plus large contient toute la plage non signée, et la contrainte CHECK écarte les valeurs négatives comme le faisait MySQL.unsigned_widened
ZEROFILL and display widthssuppriméLe remplissage par des zéros est une façon d'afficher un nombre, pas une partie du nombre. Les nombres sont conservés ; formatez-les à la lecture si le remplissage compte.zerofill_dropped
FLOAT(M,D)real ou float, sans l'échelleLes flottants SQL Server n'ont pas d'échelle fixe. Les valeurs stockées sont copiées telles quelles.float_scale_dropped
DECIMAL(p,s)decimal(p,s) jusqu'à 38 chiffres ; nvarchar au-delàLe decimal de SQL Server contient 38 chiffres. Les décimaux plus larges sont gardés en texte pour que chaque chiffre reste exact.decimal_as_text
BIT(1), BIT(n)bit ; bigint jusqu'à 63 bits ; decimal(20,0) pour BIT(64)Un seul bit est un oui ou un non ; les champs de bits plus larges sont stockés comme le nombre que forment leurs bits.
zero, partial or impossible dates (0000-00-00, 2024-02-30)NULLSQL Server ne stocke que de vraies dates du calendrier. MySQL garde les dates zéro et impossibles quand son mode SQL les autorise ; elles deviennent NULL et le rapport les compte.invalid_date_null
NOT NULL columns with values that become NULLNOT NULL retiréUne colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait.not_null_relaxed
DEFAULT '0000-00-00'aucune valeur par défautUne valeur par défaut que SQL Server ne peut pas stocker est omise plutôt que remplacée par une date inventée.zero_date_default
TIMEtime si chaque valeur tient dans une journée, sinon nvarcharLe TIME de MySQL est une durée de -838:59:59 à 838:59:59 ; le time de SQL Server est une heure du jour. Une colonne avec des valeurs plus longues ou négatives les garde en texte.time_as_interval
YEARsmallint avec un CHECK de sa plageSQL Server n'a pas de type année ; le CHECK garde les mêmes valeurs que MySQL autorise.
CHAR(n), VARCHAR(n)nvarchar(n)nvarchar contient tous les caractères sur chaque version prise en charge, et MySQL renvoie les valeurs CHAR sans espaces de fin, telles que nvarchar les garde.
text with characters past U+FFFF (emoji) in VARCHAR(n)nvarchar(2n), ou nvarchar(max) au-delà de 4000nvarchar compte en unités UTF-16 et un emoji en prend deux ; la colonne a donc la place pour chaque valeur.text_length_widened
DATETIMEdatetime2Un DATETIME est une date et une heure locales, sans fuseau horaire, comme datetime2.
TIMESTAMPdatetimeoffset dans le fuseau horaire indiqué par le dump, UTC s'il n'en indique aucunUn TIMESTAMP est un instant. Les dumps indiquent le fuseau dans lequel ils l'ont écrit (mysqldump écrit en UTC) ; sinon, les valeurs sont lues en UTC et le rapport le signale.timestamp_zone_assumed
ENUMnvarchar avec un CHECK de ses valeursUn texte avec une contrainte CHECK garde les mêmes valeurs.
ENUM holding '' (MySQL's error value)la valeur vide autorisée par le CHECKMySQL stocke une chaîne vide quand une valeur invalide entre dans un ENUM avec un mode SQL permissif. Ces lignes sont conservées et la contrainte CHECK les autorise.enum_invalid_value
ENUM holding values outside its listpas de CHECKLes valeurs absentes de la liste feraient échouer la contrainte CHECK, qui n'est donc pas créée.enum_check_skipped
SETnvarchar tel que MySQL l'écrit ('a,b')SQL Server n'a pas de tableaux ; le texte est celui que MySQL renvoie.
JSONnvarchar(max)Les fonctions JSON de SQL Server lisent le JSON depuis du texte. Un CHECK ISJSON refuserait avant SQL Server 2022 des valeurs scalaires comme 1 ou "x", que MySQL garde.
NUL bytes in textconservénvarchar peut contenir un caractère NUL, donc la valeur est copiée telle quelle.
text that isn't valid in its character setles octets invalides deviennent le caractère de remplacementLe texte doit être lu comme des caractères pour être écrit en nvarchar.invalid_utf8_replaced
text decoded twice (ñ)copié tel quelLe dump contient exactement ces caractères, ils sont donc copiés ; le rapport les signale.mojibake_suspected
AUTO_INCREMENTIDENTITY, avec le compteur placé après les identifiants copiésLes identifiants copiés se chargent avec IDENTITY_INSERT, et le compteur reprend après le plus élevé ou après l'AUTO_INCREMENT du dump, selon le plus grand.
MyISAM AUTO_INCREMENT on the second column of a keyun seul compteur pour la tableMyISAM compte par groupe de la première colonne de la clé ; SQL Server a un compteur par table.myisam_group_autoincrement
ON UPDATE CURRENT_TIMESTAMPun déclencheur AFTER UPDATELe déclencheur met la colonne à l'heure actuelle quand une mise à jour ne la définit pas. Il fait la jointure sur la clé primaire, donc la table doit en avoir une.on_update_trigger
ON UPDATE CURRENT_TIMESTAMP on a table without a primary keynon reportéLe déclencheur trouve les lignes mises à jour par leur clé primaire ; sans clé primaire, il ne peut pas.on_update_without_key
generated columnscolonnes calculées, PERSISTED quand la source les stockeSQL Server les calcule des deux mêmes façons.
generated columns with functions SQL Server lacksune colonne simpleUne formule qui ne peut pas être écrite pour SQL Server laisse une colonne simple et une ligne dans le rapport.generated_not_translated
INVISIBLE columnscolonnes ordinairesSQL Server n'a pas de colonnes invisibles.invisible_column
CHECK constraintstraduites, en ligne dans CREATE TABLELes CHECK en ligne sont vérifiés au chargement de chaque ligne.
CHECK constraints with functions SQL Server lacksnon crééeUne contrainte CHECK qui ne peut pas être écrite pour SQL Server est omise et signalée.check_skipped
CHECK ... NOT ENFORCEDnon crééeMySQL garde ces contraintes CHECK sans les appliquer, donc les lignes peuvent les enfreindre.check_not_enforced
defaults with functions SQL Server lacksaucune valeur par défautUne valeur par défaut qui ne peut pas être écrite pour SQL Server est omise et signalée.default_not_translated
keys and indexes on a prefix, c(20)un index sur la colonne entièreSQL Server indexe des colonnes entières ; une clé unique sur un préfixe est aussi unique sur la colonne entière, donc chaque ligne se charge.prefix_whole_column
FULLTEXT indexesnon crééeLa recherche plein texte de SQL Server demande un catalogue et ses propres requêtes.fulltext_not_created
SPATIAL indexesnon crééeUn index spatial sur une colonne geometry demande une zone englobante que le dump n'indique pas.spatial_index_not_created
functional indexes, and indexes on columns of unlimited lengthnon crééSQL Server n'indexe ni les expressions ni les colonnes nvarchar(max) et varbinary(max).index_skipped
foreign keysaprès les données WITH NOCHECK, puis vérifiée avec un avertissement sur les orphelinsLes dumps se chargent avec FOREIGN_KEY_CHECKS=0 et MyISAM ne vérifie jamais, donc les lignes sans parent sont fréquentes. La clé est créée d'abord et vérifiée en dernier ; des orphelins la laissent non vérifiée avec un avertissement au lieu d'arrêter le chargement.
ON DELETE or ON UPDATE that cascades in a cycle or along a second pathNO ACTIONSQL Server refuse les cascades qui pourraient atteindre une table deux fois ; MySQL les autorise.foreign_key_action_dropped
foreign keys to columns without a unique keynon crééeSQL Server exige une clé primaire ou un index unique sans NULL sur les colonnes référencées ; InnoDB non.foreign_key_skipped
table and column namestels qu'écrits ; renommés s'ils ne diffèrent que par la casseLes noms SQL Server ignorent la casse avec la collation habituelle.identifier_renamed
names over 116 charactersraccourciLes noms SQL Server font 128 caractères au plus, dont certains pour les numéros qui distinguent les noms.name_shortened
GEOMETRY, POINT, POLYGON...geometry, avec le SRID de chaque valeurLe type geometry propre à SQL Server garde chaque forme et son système de référence spatiale.
INET4, INET6, UUID (MariaDB)nvarchar(39), uniqueidentifieruniqueidentifier est l'UUID de SQL Server ; les adresses sont gardées en texte.
BINARY, VARBINARY, BLOBbinary, varbinary, varbinary(max)Les octets restent des octets.
PARTITION BYune seule tableLes lignes sont les mêmes ; partitionnez à nouveau la table dans SQL Server si besoin.partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)une table avec les lignes actuellesUn dump ne contient que les lignes actuelles.system_versioning_dropped
MyISAM, MEMORY and other enginesune table ordinaireSQL Server a un seul moteur de tables.engine_dropped
views, triggers, procedures, functions and eventslistés dans le rapportLeur code est écrit dans le langage de MySQL ; ils sont donc listés pour que vous les recréiez.not_converted_objects
dumps without CREATE TABLEtypes déduits des valeursUn dump fait avec --no-create-info ne contient que des lignes, donc les types viennent des valeurs.no_schema
geometries in a dump without CREATE TABLEgeometryLe format de géométrie de MySQL est reconnu à partir des valeurs.
_ci collationsla collation de la base, en général insensible à la casseSQL Server compare le texte sans tenir compte de la casse avec sa collation habituelle, comme le _ci de MySQL.
SET NAMES utf8 from utf8mb4 tablesconverti, avec un avertissementLe mysqldump de MySQL 5.x écrit par défaut en utf8 sur 3 octets et remplace chaque emoji par un point d'interrogation avant qu'un convertisseur ne voie le fichier.dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8lu comme Latin-1 (Windows-1252)Le latin1 de MySQL est le Windows-1252, l'encodage habituel de ces dumps.charset_guessed
sjis, cp932, gbk, big5 dumpslu comme UTF-8, avec un avertissementCes encodages ne sont pas encore décodés.unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rowsévaluéesCertains outils de dump écrivent les valeurs sous forme de ces appels ; ils sont lus comme les valeurs qu'ils produisent, le WKT géographique étant remis avec la longitude en premier.
other expressions in rowsNULLUn convertisseur qui n'exécute pas de base de données ne peut pas les évaluer.expression_value
DEFAULT in VALUESla valeur par défaut de la colonneUne valeur par défaut littérale est copiée dans la ligne.default_keyword_filled
DEFAULT in VALUES without a literal defaultNULLIl n'y a aucune valeur à copier.default_keyword_null
REPLACE and INSERT IGNORElignes simplesUn dump a une ligne par clé, donc les lignes sont les mêmes.replace_as_insert
types IntoSQL doesn't knownvarchar(max)Le texte contient n'importe quelle valeur ; changez le type après le chargement.unknown_type
values that don't fit their columnNULLUn dump endommagé ou écrit à la main peut contenir des valeurs que sa colonne n'accepte pas ; elles deviennent NULL pour que le reste se charge.invalid_value_null
unreadable geometriesNULLDes octets qui ne forment pas une géométrie ne peuvent pas être stockés comme telle.bad_geometry
CREATE SEQUENCE (MariaDB)CREATE SEQUENCE ... AS bigint, avec sa prochaine valeurSQL Server a des séquences avec les mêmes options ; chacune reprend là où le dump l'a laissée.
VECTOR(n) (MariaDB 11.7+)nvarchar(max) avec les flottants en tableau JSONSeul SQL Server 2025 a un type vector ; un tableau JSON garde chaque flottant dans toutes les versions.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.

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

Pas de réponse ici ? Écrivez-nous depuis la page de contact, une personne vous répond. Page de contact

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.