Each row is a type from SQL Server that SQLite stores differently: what the SQLite script gets, why, and the line the report writes about it. The rows come from the converter's own rules, so this page matches what it does.
Convert in the browser: SQL Server to SQLite opens the converter set up for this pair. The SQL Server to SQLite migration guide covers dumping, loading and the rules for keys, indexes and names.
A report line is a fix when the converter changed something and lists it, or a problem when a value or object is worth a look.
Numbers#
| In SQL Server |
In SQLite |
Why |
Report line |
| tinyint |
INTEGER with a CHECK that it isn't negative |
SQL Server's tinyint runs from 0 to 255; a check keeps its range. |
unsigned_widened (fix) |
| decimal(p,s) past 15 digits, money |
TEXT |
SQLite keeps about 15 significant digits in a number. Wider numbers are kept as text so every digit stays exact. |
decimal_as_text (fix) |
Booleans and bits#
| In SQL Server |
In SQLite |
Why |
Report line |
| bit |
INTEGER 0 or 1 with a CHECK |
SQLite has no boolean type; its own true and false are 1 and 0. |
None |
Text#
| In SQL Server |
In SQLite |
Why |
Report line |
| char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text |
VARCHAR(n) and TEXT, not enforced |
SQLite keeps the declared type for tools to read but doesn't limit the length. |
None |
| NUL characters in text |
kept |
SQLite text can hold a NUL character, so the value is copied as it is. |
None |
| text that isn't valid in its encoding |
the bad bytes as the replacement character |
The script is UTF-8 and every value has to be valid text. |
invalid_utf8_replaced (problem) |
Dates and times#
| In SQL Server |
In SQLite |
Why |
Report line |
| date, datetime, datetime2, smalldatetime |
DATETIME as ISO 8601 text, every digit kept |
SQLite stores dates as text its date functions read. |
None |
| datetimeoffset |
TIMESTAMP as ISO 8601 text in UTC |
SQLite has no type that keeps an offset, so each moment is written in UTC: the same instant whatever offset it had. |
moments_as_utc (fix) |
| time |
TIME as text |
SQLite keeps times as text, with every digit. |
None |
| dates that aren't valid |
NULL |
A value that isn't a date becomes NULL and the report counts it. |
date_out_of_range (problem) |
Binary#
| In SQL Server |
In SQLite |
Why |
Report line |
| binary, varbinary, image |
BLOB |
Bytes stay bytes. |
None |
| rowversion, timestamp |
BLOB, empty |
SQL Server sets a row version by itself and SSMS scripts no values for it. |
rowversion_empty (fix) |
JSON, spatial and other types#
| In SQL Server |
In SQLite |
Why |
Report line |
| json (SQL Server 2025) |
TEXT |
The same JSON values, which SQLite's JSON functions read. |
None |
| uniqueidentifier |
TEXT |
The same identifiers, written in lowercase. |
None |
| geometry, geography |
BLOB with SQL Server's own bytes |
SSMS writes spatial values in SQL Server's serialization, which is kept byte for byte. |
spatial_as_native (fix) |
| xml, sql_variant, hierarchyid, vector |
TEXT |
SQLite has no equivalent type; xml and sql_variant keep each value's text and hierarchyid its path, such as /1/2/. |
type_replaced (fix) |
| types IntoSQL doesn't know |
TEXT |
Text holds any value; change the type after loading. |
unknown_type (problem) |
Counters and identities#
| In SQL Server |
In SQLite |
Why |
Report line |
| IDENTITY |
INTEGER PRIMARY KEY AUTOINCREMENT, continuing after the highest id |
SQLite counts a whole integer primary key, and AUTOINCREMENT keeps ids from being reused. |
None |
| IDENTITY columns that aren't the whole primary key |
INTEGER without a counter |
SQLite only counts a column that is the whole primary key, so the column keeps its values and new rows need theirs. |
counter_dropped (problem) |
Other pairs#