Converta MySQL para SQL Server
Solte um dump do mysqldump, mariadb-dump, mysqlpump, phpMyAdmin ou Adminer, em .sql ou .sql.gz, e baixe um script do SQL Server com as mesmas tabelas, chaves, índices e dados. Cada valor que o SQL Server não aceita como está, e cada objeto que ele não traz, aparece no relatório.
18 linhas convertidas, 10 correções, nenhuma rejeitada
Tabelas em shop_2024.sqlDump do MySQL 8.0.46 · gerado por mysqldump · utf8mb4
customers8 linhas4
7 colunas id bigint not null name nvarchar(200) not null email nvarchar(150) not null country nvarchar(2) not null is_active bit not null signed_up date created_at datetimeoffset(0) not null orders10 linhas6
9 colunas id bigint not null customer_id bigint not null status nvarchar(9) not null total decimal(10,2) not null items int not null ordered_at datetime2(0) not null shipped_at datetime2(0) note nvarchar(510) updated_at datetimeoffset(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
Correções
- "id" de customers é sem sinal, então virou bigint com um CHECK de que não é negativa.
- "name" de customers contém caracteres que o SQL Server conta em dobro, como emoji, então vira nvarchar(200).
- "signed_up" de customers agora aceita NULL: alguns dos seus valores não puderam ser guardados e são NULL.
- O valor padrão de "signed_up" em customers, 0000‑00‑00, não é uma data que o SQL Server aceite, então a coluna fica sem valor padrão.
- "customer_id" de orders é sem sinal, então virou bigint com um CHECK de que não é negativa.
- "id" de orders é sem sinal, então virou bigint com um CHECK de que não é negativa.
- "items" de orders é sem sinal, então virou int com um CHECK de que não é negativa.
- "note" de orders contém caracteres que o SQL Server conta em dobro, como emoji, então vira nvarchar(510).
- 1 linha de "status" em orders contém o valor vazio que o MySQL guarda para entradas inválidas; o CHECK dos valores o permite.
- "updated_at" de orders muda para a hora atual a cada atualização; no SQL Server, um gatilho faz isso.
Para revisar
- 1 valor em "signed_up" de customers é uma data zero ou impossível, como 0000‑00‑00, que o SQL Server não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.
- 1 valor em "shipped_at" de orders é uma data zero ou impossível, como 0000‑00‑00 00:00:00, que o SQL Server não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.
Seu arquivo é convertido neste computador e nunca é enviado.
Outros exemplos:
O que muda do MySQL para o SQL Server
Cada linha é uma regra que o conversor aplica, com a linha do relatório que ele escreve quando a regra muda algo nos seus dados.
TINYINT(1), BOOL
bit quando todo valor é 0 ou 1, senão smallint
O BOOL do MySQL é um TINYINT(1) que aceita qualquer número de -128 a 127. Uma coluna que só contém 0 e 1 vira bit; uma que contém 2 ou -1 continua sendo número, para que nenhum valor mude de significado.
Linha do relatório: bool_kept_numeric
UNSIGNED integers
TINYINT UNSIGNED como tinyint; os outros como o próximo inteiro mais largo com um CHECK de que não é negativo, BIGINT UNSIGNED como bigint quando todo valor cabe, senão decimal(38,0)
O SQL Server não tem inteiros sem sinal, exceto tinyint, que vai de 0 a 255. Um tipo mais largo comporta todo o intervalo sem sinal, e o CHECK impede valores negativos, como o MySQL fazia.
Linha do relatório: unsigned_widened
ZEROFILL and display widths
descartado
O preenchimento com zeros é uma forma de exibir um número, não parte dele. Os números são mantidos; formate-os na leitura se o preenchimento for importante.
Linha do relatório: zerofill_dropped
FLOAT(M,D)
real ou float, sem a escala
Os floats do SQL Server não têm escala fixa. Os valores guardados são copiados como estão.
Linha do relatório: float_scale_dropped
DECIMAL(p,s)
decimal(p,s) até 38 dígitos; nvarchar acima disso
O decimal do SQL Server comporta 38 dígitos. Decimais mais largos ficam como texto, para que cada dígito continue exato.
Linha do relatório: decimal_as_text
BIT(1), BIT(n)
bit; bigint até 63 bits; decimal(20,0) para BIT(64)
Um único bit é um sim ou não; campos de bits mais largos são guardados como o número que seus bits formam.
zero, partial or impossible dates (0000-00-00, 2024-02-30)
NULL
O SQL Server só guarda datas reais do calendário. O MySQL mantém datas zero e impossíveis quando o modo SQL permite; elas viram NULL e o relatório as conta.
Linha do relatório: invalid_date_null
NOT NULL columns with values that become NULL
NOT NULL removido
Uma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia.
Linha do relatório: not_null_relaxed
DEFAULT '0000-00-00'
sem valor padrão
Um valor padrão que o SQL Server não consegue guardar fica de fora em vez de ser trocado por uma data inventada.
Linha do relatório: zero_date_default
TIME
time quando todo valor cabe em um dia, senão nvarchar
O TIME do MySQL é uma duração de -838:59:59 a 838:59:59; o time do SQL Server é uma hora do dia. Uma coluna com valores maiores ou negativos os mantém como texto.
Linha do relatório: time_as_interval
YEAR
smallint com um CHECK do intervalo
O SQL Server não tem tipo de ano; o CHECK mantém os mesmos valores que o MySQL permite.
CHAR(n), VARCHAR(n)
nvarchar(n)
nvarchar comporta qualquer caractere em todas as versões suportadas, e o MySQL retorna valores CHAR sem espaços finais, como o nvarchar os mantém.
text with characters past U+FFFF (emoji) in VARCHAR(n)
nvarchar(2n), ou nvarchar(max) acima de 4000
nvarchar conta unidades UTF-16 e um emoji ocupa duas, então a coluna ganha espaço para todo valor.
Linha do relatório: text_length_widened
DATETIME
datetime2
Um DATETIME é a leitura de um relógio de parede sem fuso horário, como o datetime2.
TIMESTAMP
datetimeoffset no fuso horário que o dump informa, UTC quando ele não informa nenhum
Um TIMESTAMP é um instante. Os dumps informam o fuso em que foram escritos (o mysqldump escreve em UTC); sem isso, os valores são lidos como UTC e o relatório avisa.
Linha do relatório: timestamp_zone_assumed
ENUM
nvarchar com um CHECK dos valores
Texto com CHECK mantém os mesmos valores.
ENUM holding '' (MySQL's error value)
o valor vazio, permitido pelo CHECK
O MySQL guarda uma string vazia quando um valor inválido entra em um ENUM em um modo SQL permissivo. Essas linhas são mantidas e o CHECK as permite.
Linha do relatório: enum_invalid_value
ENUM holding values outside its list
sem CHECK
Valores que a lista não nomeia falhariam no CHECK, então o CHECK não é criado.
Linha do relatório: enum_check_skipped
SET
nvarchar como o MySQL escreve ('a,b')
O SQL Server não tem arrays; o texto é o que o MySQL retorna.
JSON
nvarchar(max)
As funções JSON do SQL Server leem JSON a partir de texto. Um CHECK com ISJSON recusaria valores escalares como 1 ou "x" antes do SQL Server 2022, e o MySQL os mantém.
NUL bytes in text
mantido
nvarchar aceita o caractere NUL, então o valor é copiado como está.
text that isn't valid in its character set
os bytes inválidos como o caractere de substituição
O texto precisa ser lido como caracteres para ser escrito como nvarchar.
Linha do relatório: invalid_utf8_replaced
text decoded twice (ñ)
copiado como está
O dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta.
Linha do relatório: mojibake_suspected
AUTO_INCREMENT
IDENTITY, com o contador ajustado depois dos ids copiados
Os ids copiados carregam com IDENTITY_INSERT, e o contador continua depois do maior deles ou do AUTO_INCREMENT do dump, o que for maior.
MyISAM AUTO_INCREMENT on the second column of a key
um contador para a tabela
O MyISAM conta por grupo da primeira coluna da chave; o SQL Server tem um contador por tabela.
Linha do relatório: myisam_group_autoincrement
ON UPDATE CURRENT_TIMESTAMP
um gatilho AFTER UPDATE
O gatilho define a coluna com a hora atual quando uma atualização não a define. Ele faz o join pela chave primária, então a tabela precisa de uma.
Linha do relatório: on_update_trigger
ON UPDATE CURRENT_TIMESTAMP on a table without a primary key
não levado
O gatilho encontra as linhas atualizadas pela chave primária; sem ela, não consegue.
Linha do relatório: on_update_without_key
generated columns
colunas computadas, PERSISTED quando a origem as armazena
O SQL Server as calcula dos mesmos dois jeitos.
generated columns with functions SQL Server lacks
uma coluna simples
Uma fórmula que não pode ser escrita para o SQL Server deixa uma coluna simples e uma linha no relatório.
Linha do relatório: generated_not_translated
INVISIBLE columns
colunas comuns
O SQL Server não tem colunas invisíveis.
Linha do relatório: invisible_column
CHECK constraints
traduzido, dentro do CREATE TABLE
Os CHECKs são testados à medida que cada linha carrega.
CHECK constraints with functions SQL Server lacks
não criado
Um CHECK que não pode ser escrito para o SQL Server fica de fora e é informado no relatório.
Linha do relatório: check_skipped
CHECK ... NOT ENFORCED
não criado
O MySQL mantém esses CHECKs sem aplicá-los, então as linhas podem violá-los.
Linha do relatório: check_not_enforced
defaults with functions SQL Server lacks
sem valor padrão
Um valor padrão que não pode ser escrito para o SQL Server fica de fora e é informado no relatório.
Linha do relatório: default_not_translated
keys and indexes on a prefix, c(20)
um índice sobre a coluna inteira
O SQL Server indexa colunas inteiras; uma chave única em um prefixo também é única na coluna inteira, então todas as linhas carregam.
Linha do relatório: prefix_whole_column
FULLTEXT indexes
não criado
A busca de texto completo do SQL Server precisa de um catálogo e de consultas próprias.
Linha do relatório: fulltext_not_created
SPATIAL indexes
não criado
Um índice espacial em uma coluna geometry precisa de uma caixa delimitadora que o dump não informa.
Linha do relatório: spatial_index_not_created
functional indexes, and indexes on columns of unlimited length
não criado
O SQL Server não indexa expressões nem colunas nvarchar(max) e varbinary(max).
Linha do relatório: index_skipped
foreign keys
depois dos dados WITH NOCHECK, e então verificada com um aviso sobre órfãos
Os dumps são carregados com FOREIGN_KEY_CHECKS=0 e o MyISAM nunca verifica, então linhas sem pai são comuns. A chave é criada primeiro e verificada por último; órfãos a deixam sem verificação com um aviso, em vez de parar a carga.
ON DELETE or ON UPDATE that cascades in a cycle or along a second path
NO ACTION
O SQL Server recusa cascatas que poderiam chegar a uma tabela duas vezes; o MySQL as permite.
Linha do relatório: foreign_key_action_dropped
foreign keys to columns without a unique key
não criada
O SQL Server exige uma chave primária ou um índice único sem NULLs nas colunas referenciadas; o InnoDB não.
Linha do relatório: foreign_key_skipped
table and column names
como escritos; renomeados quando diferem só em maiúsculas e minúsculas
Os nomes do SQL Server ignoram maiúsculas e minúsculas na collation usual.
Linha do relatório: identifier_renamed
names over 116 characters
encurtado
Os nomes do SQL Server têm até 128 caracteres, parte deles para os números que mantêm os nomes distintos.
Linha do relatório: name_shortened
GEOMETRY, POINT, POLYGON...
geometry, com o SRID de cada valor
O tipo geometry próprio do SQL Server mantém cada forma e seu sistema de referência espacial.
INET4, INET6, UUID (MariaDB)
nvarchar(39), uniqueidentifier
uniqueidentifier é o UUID do SQL Server; os endereços ficam como texto.
BINARY, VARBINARY, BLOB
binary, varbinary, varbinary(max)
Bytes continuam sendo bytes.
PARTITION BY
uma tabela
As linhas são as mesmas; particione a tabela de novo no SQL Server se precisar.
Linha do relatório: partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)
uma tabela com as linhas atuais
Um dump contém só as linhas atuais.
Linha do relatório: system_versioning_dropped
MyISAM, MEMORY and other engines
uma tabela comum
O SQL Server tem um único mecanismo de tabelas.
Linha do relatório: engine_dropped
views, triggers, procedures, functions and events
listados no relatório
O código deles é escrito na linguagem do MySQL, então eles são listados para você recriá-los.
Linha do relatório: not_converted_objects
dumps without CREATE TABLE
tipos deduzidos dos valores
Um dump feito com --no-create-info só tem linhas, então os tipos vêm dos valores.
Linha do relatório: no_schema
geometries in a dump without CREATE TABLE
geometry
O formato de geometria do MySQL é reconhecido pelos valores.
_ci collations
a collation do banco de dados, geralmente sem diferenciar maiúsculas
O SQL Server compara texto sem diferenciar maiúsculas na collation usual, como faz o _ci do MySQL.
SET NAMES utf8 from utf8mb4 tables
convertido, com um aviso
O mysqldump do MySQL 5.x escreve utf8 de 3 bytes por padrão e troca cada emoji por um ponto de interrogação antes que qualquer conversor veja o arquivo.
Linha do relatório: dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8
lido como Latin-1 (Windows-1252)
O latin1 do MySQL é o Windows-1252, a codificação comum desses dumps.
Linha do relatório: charset_guessed
sjis, cp932, gbk, big5 dumps
lido como UTF-8, com um aviso
Essas codificações ainda não são decodificadas.
Linha do relatório: unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows
avaliadas
Algumas ferramentas de dump escrevem valores como essas chamadas; elas são lidas como os valores que produzem, com o WKT geográfico convertido para longitude primeiro.
other expressions in rows
NULL
Um conversor que não executa um banco de dados não consegue avaliá-las.
Linha do relatório: expression_value
DEFAULT in VALUES
o valor padrão da coluna
Um valor padrão literal é copiado para a linha.
Linha do relatório: default_keyword_filled
DEFAULT in VALUES without a literal default
NULL
Não há valor para copiar.
Linha do relatório: default_keyword_null
REPLACE and INSERT IGNORE
linhas simples
Um dump tem uma linha por chave, então as linhas são as mesmas.
Linha do relatório: replace_as_insert
types IntoSQL doesn't know
nvarchar(max)
O tipo text aceita qualquer valor; mude o tipo depois da carga.
Linha do relatório: unknown_type
values that don't fit their column
NULL
Um dump danificado ou escrito à mão pode conter valores que a coluna não aceita; eles viram NULL para que o resto carregue.
Linha do relatório: invalid_value_null
unreadable geometries
NULL
Bytes que não são uma geometria não podem ser guardados como uma.
Linha do relatório: bad_geometry
CREATE SEQUENCE (MariaDB)
CREATE SEQUENCE ... AS bigint, com o próximo valor
O SQL Server tem sequências com as mesmas opções; cada uma continua de onde o dump parou.
VECTOR(n) (MariaDB 11.7+)
nvarchar(max) com os floats como array JSON
Só o SQL Server 2025 tem tipo vector; um array JSON mantém cada float em qualquer versão.
Linha do relatório: type_replaced
| No MySQL | No SQL Server | Linha do relatório |
|---|---|---|
| TINYINT(1), BOOL | bit quando todo valor é 0 ou 1, senão smallintO BOOL do MySQL é um TINYINT(1) que aceita qualquer número de -128 a 127. Uma coluna que só contém 0 e 1 vira bit; uma que contém 2 ou -1 continua sendo número, para que nenhum valor mude de significado. | bool_kept_numeric |
| UNSIGNED integers | TINYINT UNSIGNED como tinyint; os outros como o próximo inteiro mais largo com um CHECK de que não é negativo, BIGINT UNSIGNED como bigint quando todo valor cabe, senão decimal(38,0)O SQL Server não tem inteiros sem sinal, exceto tinyint, que vai de 0 a 255. Um tipo mais largo comporta todo o intervalo sem sinal, e o CHECK impede valores negativos, como o MySQL fazia. | unsigned_widened |
| ZEROFILL and display widths | descartadoO preenchimento com zeros é uma forma de exibir um número, não parte dele. Os números são mantidos; formate-os na leitura se o preenchimento for importante. | zerofill_dropped |
| FLOAT(M,D) | real ou float, sem a escalaOs floats do SQL Server não têm escala fixa. Os valores guardados são copiados como estão. | float_scale_dropped |
| DECIMAL(p,s) | decimal(p,s) até 38 dígitos; nvarchar acima dissoO decimal do SQL Server comporta 38 dígitos. Decimais mais largos ficam como texto, para que cada dígito continue exato. | decimal_as_text |
| BIT(1), BIT(n) | bit; bigint até 63 bits; decimal(20,0) para BIT(64)Um único bit é um sim ou não; campos de bits mais largos são guardados como o número que seus bits formam. | |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULLO SQL Server só guarda datas reais do calendário. O MySQL mantém datas zero e impossíveis quando o modo SQL permite; elas viram NULL e o relatório as conta. | invalid_date_null |
| NOT NULL columns with values that become NULL | NOT NULL removidoUma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia. | not_null_relaxed |
| DEFAULT '0000-00-00' | sem valor padrãoUm valor padrão que o SQL Server não consegue guardar fica de fora em vez de ser trocado por uma data inventada. | zero_date_default |
| TIME | time quando todo valor cabe em um dia, senão nvarcharO TIME do MySQL é uma duração de -838:59:59 a 838:59:59; o time do SQL Server é uma hora do dia. Uma coluna com valores maiores ou negativos os mantém como texto. | time_as_interval |
| YEAR | smallint com um CHECK do intervaloO SQL Server não tem tipo de ano; o CHECK mantém os mesmos valores que o MySQL permite. | |
| CHAR(n), VARCHAR(n) | nvarchar(n)nvarchar comporta qualquer caractere em todas as versões suportadas, e o MySQL retorna valores CHAR sem espaços finais, como o nvarchar os mantém. | |
| text with characters past U+FFFF (emoji) in VARCHAR(n) | nvarchar(2n), ou nvarchar(max) acima de 4000nvarchar conta unidades UTF-16 e um emoji ocupa duas, então a coluna ganha espaço para todo valor. | text_length_widened |
| DATETIME | datetime2Um DATETIME é a leitura de um relógio de parede sem fuso horário, como o datetime2. | |
| TIMESTAMP | datetimeoffset no fuso horário que o dump informa, UTC quando ele não informa nenhumUm TIMESTAMP é um instante. Os dumps informam o fuso em que foram escritos (o mysqldump escreve em UTC); sem isso, os valores são lidos como UTC e o relatório avisa. | timestamp_zone_assumed |
| ENUM | nvarchar com um CHECK dos valoresTexto com CHECK mantém os mesmos valores. | |
| ENUM holding '' (MySQL's error value) | o valor vazio, permitido pelo CHECKO MySQL guarda uma string vazia quando um valor inválido entra em um ENUM em um modo SQL permissivo. Essas linhas são mantidas e o CHECK as permite. | enum_invalid_value |
| ENUM holding values outside its list | sem CHECKValores que a lista não nomeia falhariam no CHECK, então o CHECK não é criado. | enum_check_skipped |
| SET | nvarchar como o MySQL escreve ('a,b')O SQL Server não tem arrays; o texto é o que o MySQL retorna. | |
| JSON | nvarchar(max)As funções JSON do SQL Server leem JSON a partir de texto. Um CHECK com ISJSON recusaria valores escalares como 1 ou "x" antes do SQL Server 2022, e o MySQL os mantém. | |
| NUL bytes in text | mantidonvarchar aceita o caractere NUL, então o valor é copiado como está. | |
| text that isn't valid in its character set | os bytes inválidos como o caractere de substituiçãoO texto precisa ser lido como caracteres para ser escrito como nvarchar. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiado como estáO dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta. | mojibake_suspected |
| AUTO_INCREMENT | IDENTITY, com o contador ajustado depois dos ids copiadosOs ids copiados carregam com IDENTITY_INSERT, e o contador continua depois do maior deles ou do AUTO_INCREMENT do dump, o que for maior. | |
| MyISAM AUTO_INCREMENT on the second column of a key | um contador para a tabelaO MyISAM conta por grupo da primeira coluna da chave; o SQL Server tem um contador por tabela. | myisam_group_autoincrement |
| ON UPDATE CURRENT_TIMESTAMP | um gatilho AFTER UPDATEO gatilho define a coluna com a hora atual quando uma atualização não a define. Ele faz o join pela chave primária, então a tabela precisa de uma. | on_update_trigger |
| ON UPDATE CURRENT_TIMESTAMP on a table without a primary key | não levadoO gatilho encontra as linhas atualizadas pela chave primária; sem ela, não consegue. | on_update_without_key |
| generated columns | colunas computadas, PERSISTED quando a origem as armazenaO SQL Server as calcula dos mesmos dois jeitos. | |
| generated columns with functions SQL Server lacks | uma coluna simplesUma fórmula que não pode ser escrita para o SQL Server deixa uma coluna simples e uma linha no relatório. | generated_not_translated |
| INVISIBLE columns | colunas comunsO SQL Server não tem colunas invisíveis. | invisible_column |
| CHECK constraints | traduzido, dentro do CREATE TABLEOs CHECKs são testados à medida que cada linha carrega. | |
| CHECK constraints with functions SQL Server lacks | não criadoUm CHECK que não pode ser escrito para o SQL Server fica de fora e é informado no relatório. | check_skipped |
| CHECK ... NOT ENFORCED | não criadoO MySQL mantém esses CHECKs sem aplicá-los, então as linhas podem violá-los. | check_not_enforced |
| defaults with functions SQL Server lacks | sem valor padrãoUm valor padrão que não pode ser escrito para o SQL Server fica de fora e é informado no relatório. | default_not_translated |
| keys and indexes on a prefix, c(20) | um índice sobre a coluna inteiraO SQL Server indexa colunas inteiras; uma chave única em um prefixo também é única na coluna inteira, então todas as linhas carregam. | prefix_whole_column |
| FULLTEXT indexes | não criadoA busca de texto completo do SQL Server precisa de um catálogo e de consultas próprias. | fulltext_not_created |
| SPATIAL indexes | não criadoUm índice espacial em uma coluna geometry precisa de uma caixa delimitadora que o dump não informa. | spatial_index_not_created |
| functional indexes, and indexes on columns of unlimited length | não criadoO SQL Server não indexa expressões nem colunas nvarchar(max) e varbinary(max). | index_skipped |
| foreign keys | depois dos dados WITH NOCHECK, e então verificada com um aviso sobre órfãosOs dumps são carregados com FOREIGN_KEY_CHECKS=0 e o MyISAM nunca verifica, então linhas sem pai são comuns. A chave é criada primeiro e verificada por último; órfãos a deixam sem verificação com um aviso, em vez de parar a carga. | |
| ON DELETE or ON UPDATE that cascades in a cycle or along a second path | NO ACTIONO SQL Server recusa cascatas que poderiam chegar a uma tabela duas vezes; o MySQL as permite. | foreign_key_action_dropped |
| foreign keys to columns without a unique key | não criadaO SQL Server exige uma chave primária ou um índice único sem NULLs nas colunas referenciadas; o InnoDB não. | foreign_key_skipped |
| table and column names | como escritos; renomeados quando diferem só em maiúsculas e minúsculasOs nomes do SQL Server ignoram maiúsculas e minúsculas na collation usual. | identifier_renamed |
| names over 116 characters | encurtadoOs nomes do SQL Server têm até 128 caracteres, parte deles para os números que mantêm os nomes distintos. | name_shortened |
| GEOMETRY, POINT, POLYGON... | geometry, com o SRID de cada valorO tipo geometry próprio do SQL Server mantém cada forma e seu sistema de referência espacial. | |
| INET4, INET6, UUID (MariaDB) | nvarchar(39), uniqueidentifieruniqueidentifier é o UUID do SQL Server; os endereços ficam como texto. | |
| BINARY, VARBINARY, BLOB | binary, varbinary, varbinary(max)Bytes continuam sendo bytes. | |
| PARTITION BY | uma tabelaAs linhas são as mesmas; particione a tabela de novo no SQL Server se precisar. | partitions_dropped |
| WITH SYSTEM VERSIONING (MariaDB) | uma tabela com as linhas atuaisUm dump contém só as linhas atuais. | system_versioning_dropped |
| MyISAM, MEMORY and other engines | uma tabela comumO SQL Server tem um único mecanismo de tabelas. | engine_dropped |
| views, triggers, procedures, functions and events | listados no relatórioO código deles é escrito na linguagem do MySQL, então eles são listados para você recriá-los. | not_converted_objects |
| dumps without CREATE TABLE | tipos deduzidos dos valoresUm dump feito com --no-create-info só tem linhas, então os tipos vêm dos valores. | no_schema |
| geometries in a dump without CREATE TABLE | geometryO formato de geometria do MySQL é reconhecido pelos valores. | |
| _ci collations | a collation do banco de dados, geralmente sem diferenciar maiúsculasO SQL Server compara texto sem diferenciar maiúsculas na collation usual, como faz o _ci do MySQL. | |
| SET NAMES utf8 from utf8mb4 tables | convertido, com um avisoO mysqldump do MySQL 5.x escreve utf8 de 3 bytes por padrão e troca cada emoji por um ponto de interrogação antes que qualquer conversor veja o arquivo. | dump_lost_four_byte_chars |
| dumps without SET NAMES whose text isn't UTF-8 | lido como Latin-1 (Windows-1252)O latin1 do MySQL é o Windows-1252, a codificação comum desses dumps. | charset_guessed |
| sjis, cp932, gbk, big5 dumps | lido como UTF-8, com um avisoEssas codificações ainda não são decodificadas. | unsupported_charset |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | avaliadasAlgumas ferramentas de dump escrevem valores como essas chamadas; elas são lidas como os valores que produzem, com o WKT geográfico convertido para longitude primeiro. | |
| other expressions in rows | NULLUm conversor que não executa um banco de dados não consegue avaliá-las. | expression_value |
| DEFAULT in VALUES | o valor padrão da colunaUm valor padrão literal é copiado para a linha. | default_keyword_filled |
| DEFAULT in VALUES without a literal default | NULLNão há valor para copiar. | default_keyword_null |
| REPLACE and INSERT IGNORE | linhas simplesUm dump tem uma linha por chave, então as linhas são as mesmas. | replace_as_insert |
| types IntoSQL doesn't know | nvarchar(max)O tipo text aceita qualquer valor; mude o tipo depois da carga. | unknown_type |
| values that don't fit their column | NULLUm dump danificado ou escrito à mão pode conter valores que a coluna não aceita; eles viram NULL para que o resto carregue. | invalid_value_null |
| unreadable geometries | NULLBytes que não são uma geometria não podem ser guardados como uma. | bad_geometry |
| CREATE SEQUENCE (MariaDB) | CREATE SEQUENCE ... AS bigint, com o próximo valorO SQL Server tem sequências com as mesmas opções; cada uma continua de onde o dump parou. | |
| VECTOR(n) (MariaDB 11.7+) | nvarchar(max) com os floats como array JSONSó o SQL Server 2025 tem tipo vector; um array JSON mantém cada float em qualquer versão. | type_replaced |
Carregue o script no SQL Server
O script cria as tabelas, copia as linhas e depois adiciona chaves, índices e chaves estrangeiras, então carrega rápido e para no primeiro erro.
sqlcmd -b -f 65001 -S localhost -d mydb -i mysql.sql_server.sqlAs chaves estrangeiras são adicionadas WITH NOCHECK e depois verificadas. Se uma linha aponta para uma linha que não existe, o script informa qual restrição e a deixa sem verificação, em vez de falhar no meio do caminho.
Para um dump grande, execute o sqlcmd na mesma máquina do servidor. Cada lote de até 1000 linhas faz commit sozinho, então o log de transações continua pequeno.
Gere o dump do MySQL para o melhor resultado
O conversor lê o que o dump contém. Estas opções mantêm mais dos seus dados nele:
- --default-character-set=utf8mb4 mantém emoji e outros caracteres de 4 bytes, que um dump em utf8 perde antes de o conversor vê-lo.
- --hex-blob escreve as colunas binárias em hexadecimal, o que sobrevive à cópia entre sistemas.
- --routines --triggers --events adicionam esses objetos ao dump, para que o relatório possa listá-los.
O que não é convertido
Visões, gatilhos, procedimentos armazenados, funções e eventos são escritos na linguagem própria de cada banco de dados. Eles aparecem no relatório pelo nome, nunca são descartados em silêncio, para que você possa reescrevê-los para o SQL Server.
Perguntas sobre MySQL para SQL Server
Não encontrou a resposta? Escreva para nós pela página de contato e uma pessoa responde. Página de contato
Meu dump é enviado?
Não. O conversor roda no seu navegador e lê o dump do seu disco em partes, então ele nunca sai do seu computador. O app para desktop e a linha de comando também convertem no seu computador.
Qual o tamanho máximo do dump?
O conversor nunca guarda o dump inteiro na memória: ele lê o arquivo duas vezes, por intervalos, e escreve o script à medida que avança. Dumps de vários gigabytes são convertidos no navegador, no app para desktop e com a linha de comando.
Ele lê dumps do MariaDB?
Sim. Dumps do mariadb-dump e do MariaDB 10.3 ao 12 são convertidos da mesma forma, incluindo as colunas INET6, INET4 e UUID do MariaDB.
O que acontece com datas 0000-00-00?
O SQL Server não tem data zero, então elas viram NULL e a coluna passa a aceitar NULL. O relatório diz quantas havia em cada coluna.
Os valores de AUTO_INCREMENT são mantidos?
Sim. Cada coluna AUTO_INCREMENT vira uma coluna IDENTITY, cada linha mantém seu id, e o próximo id continua depois do maior, ou depois do AUTO_INCREMENT da tabela, se ele for maior.
TINYINT(1) vira boolean?
Vira bit só quando todo valor da coluna é 0 ou 1. Se ela contém outros números, como 2 ou -1, continua sendo número e o relatório explica o motivo, para que nenhum valor vire 1 por acidente.
E os procedimentos armazenados e gatilhos?
Eles aparecem no relatório pelo nome e não são convertidos, porque cada banco de dados os escreve na sua própria linguagem. ON UPDATE CURRENT_TIMESTAMP é a exceção: vira um gatilho do SQL Server.
Em quais versões do SQL Server o script carrega?
SQL Server 2017 a 2025. O mesmo script carrega em cada uma delas e para no primeiro erro se algo der errado.