将 SQL Server 转换为 SQLite
拖入 SSMS 的"生成脚本"写出的包含架构和数据的脚本(.sql 或 .sql.gz,UTF-16 或 UTF-8),即可下载包含相同表、键、索引和数据的 SQLite 脚本。SQLite 无法原样存储的每个值,以及它不支持的每个对象,都会在报告中列出。
已转换 18 行,3 处修正,无拒绝
shop_2024_sqlserver.sql 中的表SQL Server 转储 · 由 SQL Server Management Objects 写出 · utf-8
orders10 行2
11 列 id INTEGER not null customer_id INTEGER not null status VARCHAR(10) not null total TEXT not null items INTEGER not null ordered_at DATETIME not null shipped_at DATETIME note TEXT details TEXT order_ref TEXT not null total_with_tax DECIMAL(12,2) customers8 行1
8 列 id INTEGER not null name VARCHAR(100) not null email VARCHAR(200) not null country VARCHAR(2) not null is_active INTEGER not null signed_up DATE created_at TIMESTAMP not null row_version BLOB
未转换
- 视图 paid_orders
- 触发器 orders_no_negative
每种数据库都用自己的语言编写这些对象。请为 SQLite 重写它们。
-- Written by IntoSQL from a SQL Server dump. Load it with: sqlite3 -bail <database> < <file>
PRAGMA foreign_keys = OFF;
PRAGMA synchronous = OFF;
BEGIN;
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER NOT NULL,
status VARCHAR(10) DEFAULT 'pending' NOT NULL,
total TEXT NOT NULL,
items INTEGER DEFAULT 1 NOT NULL,
ordered_at DATETIME NOT NULL,
shipped_at DATETIME,
note TEXT,
details TEXT,
order_ref TEXT NOT NULL,
total_with_tax DECIMAL(12,2) GENERATED ALWAYS AS (CAST(total * (1.16) AS NUMERIC)) STORED,
CONSTRAINT orders_items_check CHECK (items >= 0),
CONSTRAINT orders_check2 CHECK (status = 'cancelled' OR status = 'shipped' OR status = 'paid' OR status = 'pending'),
CONSTRAINT orders_check3 CHECK (total >= (0)),
CONSTRAINT orders_fkey FOREIGN KEY (customer_id) REFERENCES customers (id)
);
CREATE TABLE customers ( -- People who bought at least once
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(200) NOT NULL,
country VARCHAR(2) DEFAULT 'US' NOT NULL,
is_active INTEGER DEFAULT 1 NOT NULL,
signed_up DATE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
row_version BLOB,
CONSTRAINT customers_is_active_check CHECK (is_active IN (0, 1))
);
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(5,'Noah O''Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59.0000000');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'2024-04-12','2024-04-12 12:12:12.0000000');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(1,1,'shipped','129.9000',3,'2024-03-01T10:00:00.0000000','2024-03-02T16:30:00.1234567',NULL,'{"gift": false}','0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(2,2,'paid','54.0000',1,'2024-03-02T11:15:00.0000000',NULL,'Gift wrap 🎁','{"gift": true, "wrap": "red"}','1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(3,1,'cancelled','12.5000',1,'2024-03-03T09:45:00.0000000',NULL,'Customer changed their mind',NULL,'2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(4,4,'shipped','980.0000',12,'2024-03-05T02:10:00.0000000','2024-03-07T08:00:00.0000000','请小心轻放','{"fragile": true}','3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(5,5,'pending','45.7500',2,'2024-03-08T17:20:00.0000000',NULL,'Leave at the door; ring twice',NULL,'4f1e806c-7d5b-4c2e-9a99-5e6f708192a3');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(6,6,'shipped','310.4000',5,'2024-03-10T13:00:00.0000000','2024-03-11T09:00:00.0000000','Fragile: "glass"','{"fragile": true}','50f2917d-8e6c-4d3f-8baa-6f708192a3b4');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(7,8,'paid','76.2000',2,'2024-03-11T18:45:00.0000000',NULL,NULL,NULL,'6103a28e-9f7d-4e40-9cbb-708192a3b4c5');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(8,2,'shipped','19.9900',1,'2024-03-12T08:00:00.0000000','9999-12-31T23:59:59.9999999','Shipped date set to the maximum by an old import',NULL,'7214b39f-a08e-4f51-8dcc-8192a3b4c5d6');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(9,3,'shipped','64.0000',2,'2024-03-14T15:30:00.0000000','2024-03-15T10:00:00.0000000','Two parcels','{"parcels": [1, 2]}','8325c4a0-b19f-4062-9edd-92a3b4c5d6e7');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, order_ref) VALUES
(10,7,'paid','1499.0000',1,'2024-03-15T21:05:00.0000000',NULL,'C:\Users\ravi\invoice.pdf',NULL,'9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8');
-- Indexes, triggers and counters, after the rows so each index builds once.
CREATE INDEX orders_idx_orders_customer ON orders (customer_id);
CREATE INDEX orders_idx_orders_status_date ON orders (status, ordered_at);
CREATE UNIQUE INDEX customers_email ON customers (email);
UPDATE sqlite_sequence SET seq = max(seq, 0) WHERE name = 'orders';
INSERT INTO sqlite_sequence (name, seq) SELECT 'orders', 0 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'orders');
UPDATE sqlite_sequence SET seq = max(seq, 0) WHERE name = 'customers';
INSERT INTO sqlite_sequence (name, seq) SELECT 'customers', 0 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'customers');
COMMIT;
-- Rows whose foreign key finds no parent, if any: the load doesn't stop for them.
PRAGMA foreign_key_check;
修正
- orders 的 "items" 是无符号的,因此变为 INTEGER,并带有不能为负数的检查约束。
- orders 的 "total" 是 money,位数超过 SQLite 数字能保存的位数,因此存为包含每一位数字的文本。
- customers 的 "row_version" 是 SQL Server 自动设置的行版本;转储中没有它的值,因此改为 BLOB,并保持为空。
需要检查
- 源数据中有 6 个文本列比较时不区分大小写;SQLite 精确比较,因此唯一键和搜索的行为可能不同。 在需要的列上使用不区分大小写的排序规则或列类型。
- 2 个视图、触发器、例程或事件未转换;报告逐一列出了它们。 请在 SQLite 中手动重新创建它们。
- orders 上的检查约束 check1 无法为 SQLite 写出(function isjson),因此未创建。 如果它重要,请手动编写该检查约束。
- orders 上的索引 idx_orders_pending 使用了无法为 SQLite 写出的表达式(filtered index),因此未创建。 如果查询需要,请手动创建该索引。
- orders 中 "order_ref" 的默认值无法为 SQLite 写出(function uuid),因此该列没有默认值。 如果新行需要,请手动添加默认值。
文件在这台电脑上转换,永远不会上传。
其他示例:
从 SQL Server 到 SQLite 的变化
每一行是转换器应用的一条规则,以及该规则更改你的数据时在报告中写入的记录。
bit
INTEGER 0 或 1,并带有 CHECK
SQLite 没有布尔类型;它自己的 true 和 false 就是 1 和 0。
tinyint
INTEGER,并带有不能为负数的 CHECK
SQL Server 的 tinyint 范围是 0 到 255;用检查约束保持其范围。
报告记录: unsigned_widened
char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text
VARCHAR(n) 和 TEXT,不强制长度
SQLite 保留声明的类型供工具读取,但不限制长度。
decimal(p,s) past 15 digits, money
TEXT
SQLite 的数字大约保留 15 位有效数字。更宽的数字保存为文本,使每一位都保持精确。
报告记录: decimal_as_text
date, datetime, datetime2, smalldatetime
DATETIME,以 ISO 8601 文本存储,保留每一位
SQLite 将日期存储为其日期函数能读取的文本。
datetimeoffset
TIMESTAMP,存为 UTC 的 ISO 8601 文本
SQLite 没有能保留偏移量的类型,因此每个时间点都以 UTC 写出:无论原有偏移量是多少,都是同一时刻。
报告记录: moments_as_utc
time
TIME,存为文本
SQLite 以文本保存时间,保留每一位数字。
dates that aren't valid
NULL
不是日期的值变为 NULL,报告会统计其数量。
报告记录: date_out_of_range
json (SQL Server 2025)
TEXT
JSON 值相同,SQLite 的 JSON 函数可以读取。
uniqueidentifier
TEXT
标识符相同,以小写写出。
binary, varbinary, image
BLOB
字节仍然是字节。
geometry, geography
BLOB,存放 SQL Server 自己的字节
SSMS 以 SQL Server 的序列化格式写出空间值,这些字节会逐字节保留。
报告记录: spatial_as_native
rowversion, timestamp
BLOB,空
行版本由 SQL Server 自动设置,SSMS 不会为其写出值。
报告记录: rowversion_empty
xml, sql_variant, hierarchyid, vector
TEXT
SQLite 没有对应的类型;xml 和 sql_variant 保留每个值的文本,hierarchyid 保留其路径,例如 /1/2/。
报告记录: type_replaced
collations that ignore case (_CI_)
精确比较
除非另有指定,SQLite 会精确比较文本,其 NOCASE 也只对 ASCII 字母忽略大小写。
报告记录: case_insensitive_collation
IDENTITY
INTEGER PRIMARY KEY AUTOINCREMENT,从最大的 id 之后继续
SQLite 为整个整数主键计数,AUTOINCREMENT 可防止 id 被重复使用。
IDENTITY columns that aren't the whole primary key
INTEGER,没有计数器
SQLite 只为构成完整主键的列计数,因此该列保留其值,新行需要自行提供值。
报告记录: counter_dropped
CREATE SEQUENCE
不创建
SQLite 没有序列。序列分配过的值都在行中。
报告记录: sequence_not_converted
computed columns
GENERATED ALWAYS AS,PERSISTED 时为 STORED,否则为 VIRTUAL
SQLite 3.31 及更高版本以相同的两种方式计算它们,CONCAT 的写法让 NULL 像在 SQL Server 中一样视为空。
computed columns with functions SQLite lacks
普通列
无法写出的公式会留下一个普通列和一条报告记录;SSMS 不会为计算列写出值。
报告记录: generated_not_translated
defaults with functions SQLite lacks, and NEXT VALUE FOR
无默认值
无法写出的默认值会被省略,并在报告中列出。
报告记录: default_not_translated
CHECK constraints
已转换
检查约束相同,在导入每一行时检查。
CHECK constraints with functions SQLite lacks
不创建
无法写出的检查约束会被省略,并在报告中列出。
报告记录: check_skipped
CHECK constraints added WITH NOCHECK or disabled
不创建
SQL Server 不执行这些检查约束,因此行可能违反它们。
报告记录: check_not_enforced
filtered and columnstore indexes
不创建
IntoSQL 在整列上写出 b-tree 索引;其他索引请在导入后重新创建。
报告记录: index_skipped
foreign keys
在 CREATE TABLE 中,不检查地导入,然后用 PRAGMA foreign_key_check 列出
SQLite 只接受 CREATE TABLE 中的外键,且只在 PRAGMA foreign_keys 开启时检查。行在不检查的情况下导入,脚本最后列出所有没有父行的行。
foreign keys to tables the dump doesn't create
不创建
外键无法引用不存在的表。
报告记录: foreign_key_skipped
tables on a partition scheme
单个表,包含每个分区的行
行保持不变;如有需要,请在 SQLite 中重新对该表分区。
报告记录: partitions_dropped
temporal tables (SYSTEM_VERSIONING)
两个表:当前行和历史记录
表及其历史表作为普通表复制;SQLite 不会自动保留历史记录。
报告记录: system_versioning_dropped
schemas
单个文件,每个表名前加上其 schema 名
一个 SQLite 文件就是一个数据库,因此用 schema 名区分同名的表;dbo 中的表保留原名。
报告记录: schemas_merged
NOT NULL columns with values that become NULL
去除 NOT NULL
值必须变为 NULL 的列无法保留 NOT NULL,否则导入会中止。
报告记录: not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functions
在报告中列出
它们的代码用 T-SQL 编写,因此会列出来,由你重新创建。
报告记录: not_converted_objects
scripts without CREATE TABLE (data only)
根据值推断类型
只含数据的脚本只有行,因此类型来自值。
报告记录: no_schema
expressions in INSERT values
NULL
不运行数据库的转换器无法对它们求值。
报告记录: expression_value
types IntoSQL doesn't know
TEXT
文本可以容纳任何值;请在导入后更改类型。
报告记录: unknown_type
NUL characters in text
保留
SQLite 的 text 可以存储 NUL 字符,因此值按原样复制。
text that isn't valid in its encoding
错误的字节变为替换字符
脚本是 UTF-8,每个值都必须是有效文本。
报告记录: invalid_utf8_replaced
text decoded twice (ñ)
按原样复制
脚本中存储的正是这些字符,因此按原样复制;报告会指出它们。
报告记录: mojibake_suspected
| 在 SQL Server 中 | 在 SQLite 中 | 报告记录 |
|---|---|---|
| bit | INTEGER 0 或 1,并带有 CHECKSQLite 没有布尔类型;它自己的 true 和 false 就是 1 和 0。 | |
| tinyint | INTEGER,并带有不能为负数的 CHECKSQL Server 的 tinyint 范围是 0 到 255;用检查约束保持其范围。 | unsigned_widened |
| char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text | VARCHAR(n) 和 TEXT,不强制长度SQLite 保留声明的类型供工具读取,但不限制长度。 | |
| decimal(p,s) past 15 digits, money | TEXTSQLite 的数字大约保留 15 位有效数字。更宽的数字保存为文本,使每一位都保持精确。 | decimal_as_text |
| date, datetime, datetime2, smalldatetime | DATETIME,以 ISO 8601 文本存储,保留每一位SQLite 将日期存储为其日期函数能读取的文本。 | |
| datetimeoffset | TIMESTAMP,存为 UTC 的 ISO 8601 文本SQLite 没有能保留偏移量的类型,因此每个时间点都以 UTC 写出:无论原有偏移量是多少,都是同一时刻。 | moments_as_utc |
| time | TIME,存为文本SQLite 以文本保存时间,保留每一位数字。 | |
| dates that aren't valid | NULL不是日期的值变为 NULL,报告会统计其数量。 | date_out_of_range |
| json (SQL Server 2025) | TEXTJSON 值相同,SQLite 的 JSON 函数可以读取。 | |
| uniqueidentifier | TEXT标识符相同,以小写写出。 | |
| binary, varbinary, image | BLOB字节仍然是字节。 | |
| geometry, geography | BLOB,存放 SQL Server 自己的字节SSMS 以 SQL Server 的序列化格式写出空间值,这些字节会逐字节保留。 | spatial_as_native |
| rowversion, timestamp | BLOB,空行版本由 SQL Server 自动设置,SSMS 不会为其写出值。 | rowversion_empty |
| xml, sql_variant, hierarchyid, vector | TEXTSQLite 没有对应的类型;xml 和 sql_variant 保留每个值的文本,hierarchyid 保留其路径,例如 /1/2/。 | type_replaced |
| collations that ignore case (_CI_) | 精确比较除非另有指定,SQLite 会精确比较文本,其 NOCASE 也只对 ASCII 字母忽略大小写。 | case_insensitive_collation |
| IDENTITY | INTEGER PRIMARY KEY AUTOINCREMENT,从最大的 id 之后继续SQLite 为整个整数主键计数,AUTOINCREMENT 可防止 id 被重复使用。 | |
| IDENTITY columns that aren't the whole primary key | INTEGER,没有计数器SQLite 只为构成完整主键的列计数,因此该列保留其值,新行需要自行提供值。 | counter_dropped |
| CREATE SEQUENCE | 不创建SQLite 没有序列。序列分配过的值都在行中。 | sequence_not_converted |
| computed columns | GENERATED ALWAYS AS,PERSISTED 时为 STORED,否则为 VIRTUALSQLite 3.31 及更高版本以相同的两种方式计算它们,CONCAT 的写法让 NULL 像在 SQL Server 中一样视为空。 | |
| computed columns with functions SQLite lacks | 普通列无法写出的公式会留下一个普通列和一条报告记录;SSMS 不会为计算列写出值。 | generated_not_translated |
| defaults with functions SQLite lacks, and NEXT VALUE FOR | 无默认值无法写出的默认值会被省略,并在报告中列出。 | default_not_translated |
| CHECK constraints | 已转换检查约束相同,在导入每一行时检查。 | |
| CHECK constraints with functions SQLite lacks | 不创建无法写出的检查约束会被省略,并在报告中列出。 | check_skipped |
| CHECK constraints added WITH NOCHECK or disabled | 不创建SQL Server 不执行这些检查约束,因此行可能违反它们。 | check_not_enforced |
| filtered and columnstore indexes | 不创建IntoSQL 在整列上写出 b-tree 索引;其他索引请在导入后重新创建。 | index_skipped |
| foreign keys | 在 CREATE TABLE 中,不检查地导入,然后用 PRAGMA foreign_key_check 列出SQLite 只接受 CREATE TABLE 中的外键,且只在 PRAGMA foreign_keys 开启时检查。行在不检查的情况下导入,脚本最后列出所有没有父行的行。 | |
| foreign keys to tables the dump doesn't create | 不创建外键无法引用不存在的表。 | foreign_key_skipped |
| tables on a partition scheme | 单个表,包含每个分区的行行保持不变;如有需要,请在 SQLite 中重新对该表分区。 | partitions_dropped |
| temporal tables (SYSTEM_VERSIONING) | 两个表:当前行和历史记录表及其历史表作为普通表复制;SQLite 不会自动保留历史记录。 | system_versioning_dropped |
| schemas | 单个文件,每个表名前加上其 schema 名一个 SQLite 文件就是一个数据库,因此用 schema 名区分同名的表;dbo 中的表保留原名。 | schemas_merged |
| NOT NULL columns with values that become NULL | 去除 NOT NULL值必须变为 NULL 的列无法保留 NOT NULL,否则导入会中止。 | not_null_relaxed |
| views, functions, procedures, triggers, synonyms, types and partition functions | 在报告中列出它们的代码用 T-SQL 编写,因此会列出来,由你重新创建。 | not_converted_objects |
| scripts without CREATE TABLE (data only) | 根据值推断类型只含数据的脚本只有行,因此类型来自值。 | no_schema |
| expressions in INSERT values | NULL不运行数据库的转换器无法对它们求值。 | expression_value |
| types IntoSQL doesn't know | TEXT文本可以容纳任何值;请在导入后更改类型。 | unknown_type |
| NUL characters in text | 保留SQLite 的 text 可以存储 NUL 字符,因此值按原样复制。 | |
| text that isn't valid in its encoding | 错误的字节变为替换字符脚本是 UTF-8,每个值都必须是有效文本。 | invalid_utf8_replaced |
| text decoded twice (ñ) | 按原样复制脚本中存储的正是这些字符,因此按原样复制;报告会指出它们。 | mojibake_suspected |
将脚本导入 SQLite
脚本先创建表、复制行,再添加键、索引和外键,因此导入速度快,并会在遇到第一个错误时停止。
sqlite3 -bail mydb.sqlite < sql_server.sqlite.sql外键在每个表中声明,行在关闭外键检查的情况下导入。随后脚本会列出所有指向不存在的行的行,而不是中途失败。
对于较大的转储,请导入到本地磁盘上的新文件中。脚本在关闭同步的单个事务中导入全部内容,因此以磁盘速度运行,中途停止的导入也不会留下不完整的表。
命令行可将文件直接导入 SQLite 数据库,无需生成脚本,而且免费。
如何转储 SQL Server 以获得最佳结果
转换器读取转储中的内容。以下选项能让转储保留更多数据:
- 在 SSMS 中右键单击数据库,依次选择"任务"、"生成脚本",然后选择表。dbatools、mssql-scripter 以及其他基于同一库的工具也会写出相同的脚本。
- 在"高级"中,将"要编写脚本的数据的类型"设为"架构和数据"。只含架构的脚本中,表没有行。
- 以 SSMS 默认的 Unicode 或 UTF-8 保存:两者的读取方式相同,也支持 gzip。
哪些内容不会转换
视图、函数、存储过程、触发器、同义词、规则和安全策略都是用 T-SQL 编写的。它们会按名称在报告中列出,绝不会被悄悄丢弃,以便你为 SQLite 重写。
关于 SQL Server 转 SQLite 的问题
这里没有你要的答案?请通过联系页面给我们留言,会有专人回复。 联系页面
我的转储会被上传吗?
不会。转换器在你的浏览器中运行,分块从磁盘读取转储,因此转储不会离开你的电脑。桌面应用和命令行也在你的电脑上转换。
转储可以多大?
转换器从不把整个转储放进内存:它按范围读取文件两次,边读边写出脚本。几 GB 的转储可以在浏览器、桌面应用和命令行中转换。
它能读取 SSMS 保存的 UTF-16 文件吗?
能。SSMS 默认以 UTF-16 保存脚本,而转换器同样能读取 UTF-16 和 UTF-8,无论是否经过 gzip 压缩,批处理之间的 GO 也能识别。
脚本可以来自哪些 SQL Server 版本?
由 SSMS、dbatools 或 mssql-scripter 从 SQL Server 2017 及更高版本写出的脚本。每个测试脚本都来自 SQL Server 2017、2022 和 2025,并与其源数据逐个单元格比较。
IDENTITY 值会保留吗?
作为表的整个主键的 IDENTITY 列变为 INTEGER PRIMARY KEY AUTOINCREMENT,每一行都保留其 id,下一个 id 从最大的 id 之后继续。其他 IDENTITY 列保留其值,不带计数器。
money、datetimeoffset 和其他 SQL Server 类型会怎样处理?
bit 变为 0 和 1,datetime2 变为保留每一位的 ISO 8601 文本,datetimeoffset 变为 UTC 文本,宽 decimal 和 money 变为精确的文本。计算列仍为计算列。schema 变为表名前缀。
存储过程、触发器和视图怎么处理?
它们会按名称在报告中列出,但不会转换,因为每种数据库都用自己的语言编写它们。
脚本可以导入哪些 SQLite 版本?
SQLite 3.31 及更高版本。每个测试脚本都能在 3.31 和 3.54 上导入,如有问题会在第一个错误处停止。