Published: 2026-06-14

Migrate SQL Server to MySQL

Jam SQL Studio migrates SQL Server tables to MySQL — schema and data — from the Object Explorer. Right-click a table or database, point it at a MySQL (or MariaDB) connection, and Jam translates the types into MySQL's dialect, copies the rows, and verifies the counts. The headline translations: bit → tinyint(1), uniqueidentifier → char(36), datetime2 → datetime, nvarchar(max) → text, and IDENTITY → AUTO_INCREMENT.

The workflow — connect both, right-click Migrate Table to Connection…, Preview, Migrate — is shared across pairs; see the cross-engine workflow. This is the less common direction (most teams move onto PostgreSQL), but the canonical type model runs the same way; below is what's specific to SQL Server → MySQL.

SQL Server → MySQL type mapping

SQL ServerMySQLNote
bittinyint(1)MySQL's idiomatic boolean
tinyinttinyintNote: SQL Server tinyint is unsigned 0–255; MySQL tinyint is signed
smallint / int / bigintsmallint / int / bigint
realfloat
floatdouble
decimal(p,s) / numeric(p,s)decimal(p,s)Exact
moneydecimal(19,4)The money spelling is lost; value preserved
smallmoneydecimal(10,4)
char(n) / nchar(n)char(n)
varchar(n) / nvarchar(n)varchar(n)
varchar(max) / nvarchar(max) / text / ntexttextUnbounded character data
binary / varbinarybinary / varbinary
varbinary(max) / imageblobUnbounded binary
uniqueidentifierchar(36)Gotcha: no native UUID; stored as text
date / timedate / time
datetime / datetime2 / smalldatetimedatetimeTz-less
datetimeoffsettimestampLossy: MySQL has no tz-aware type — offset dropped
xml, sql_variant, hierarchyid, spatialcarried verbatim + warningNo canonical equivalent

SQL Server → MySQL gotchas

  • uniqueidentifierchar(36). MySQL has no UUID type. The GUID lands as readable 36-character text. For a smaller footprint, switch to binary(16) with UUID_TO_BIN() after migrating — but char(36) is the safe default.
  • tinyint sign flips. SQL Server tinyint is unsigned (0–255); MySQL tinyint is signed (−128–127). Values above 127 need tinyint unsigned on the MySQL side — check the source range if you used the high end.
  • datetimeoffset loses its offset. MySQL has no timezone-aware datetime, so the offset is dropped. If timezone fidelity matters, store the UTC instant plus a separate offset column.
  • Schemas become databases. SQL Server's schema.table two-part naming has no direct MySQL analogue (MySQL's "schema" is the database). The table lands in the target database you pick; objects that referenced dbo. explicitly need those references dropped.
  • Case sensitivity depends on the platform. MySQL table-name case sensitivity follows lower_case_table_names and the host filesystem — a detail that doesn't exist in SQL Server. Pick a casing convention before migrating a large schema.

What stays manual

Tables, types, constraints, indexes, and data migrate automatically. T-SQL procedural code does not translate to MySQL's stored-program dialect: views, stored procedures, functions, and triggers are a manual port. Run a cross-engine Schema Compare after migrating to get the by-name inventory of what's missing on MySQL, then rewrite each in MySQL's syntax (which, like the PostgreSQL case, differs from T-SQL in variables, error handling, and built-in functions).

Frequently asked questions

How does SQL Server bit map to MySQL?

A SQL Server bit becomes a MySQL tinyint(1), which is MySQL's idiomatic boolean, and the 0/1 values carry across directly. Both engines store the boolean as a one-byte integer, so this is a faithful, lossless mapping.

What happens to uniqueidentifier when migrating to MySQL?

MySQL has no native UUID type, so a SQL Server uniqueidentifier maps to char(36) and the GUID is stored as its 36-character text form. If storage size matters you can switch to binary(16) on the MySQL side and convert with UUID_TO_BIN, but char(36) is the readable, drop-in default Jam emits.

Does IDENTITY become AUTO_INCREMENT in MySQL?

Yes. A SQL Server IDENTITY column becomes a MySQL AUTO_INCREMENT column, and after the rows are copied the auto-increment counter is set to continue past the highest migrated id. MySQL allows one AUTO_INCREMENT column per table and it must be a key, which matches the usual IDENTITY primary-key pattern.