【数据库】AI 辅助迁移到 SQL Server
摘要:用 AI 帮把手,把 Access/Excel 数据稳稳迁到 SQL Server。
💡 这篇是 L4(进阶硬核)。它假设你已经会用 Access 建表、也大致知道 SQL 是啥(没看过可以先补 B13《用 AI 设计第一张表》、B14《AI 写查询 SQL 不求人》、B15《AI 设计规范化数据库结构》)。下面咱们真刀真枪跑一遍迁移。
一、痛点引入
你是不是也遇到过这些烦心事:
- Excel 表越存越大,几十 MB 一打开就转圈圈,公式一多直接卡死;
- Access 单个文件最多 2 GB,客户数据一多就报"数据库已达到大小上限",还动不动弹出"数据库已损坏,正在修复";
- 老板说要上报表系统、要做 BI 大屏,但 Excel/Access 撑不住多人同时读写,一协作就互相覆盖。
这时候,把数据搬进 SQL Server 是个靠谱解法。SQL Server 是微软出的一款"正经数据库"(和 Access 一样能存表,但更稳、更大、支持很多人同时用),它还有个免费版叫 Express,小团队完全够用。
可真要自己迁,麻烦来了:表怎么建?Access 的"自动编号"搬到 SQL Server 叫啥?Excel 里的日期、金额会不会导歪?表跟表之间的关系(比如"一个客户对应多张订单")迁过去还在不在?
别慌。咱们让 ChatGPT 当"迁移小助手":建表 SQL 让它出草稿,类型映射让它翻译,校验 SQL 让它写,咱们自己把控方向和最后确认。下面用"客户表 + 订单表"这个最常见的一对多关系,带你完整跑一遍。
二、目标产出
跟着做完,你会得到:
- 一个 SQL Server 数据库(Express 或任意版本都行),里面有 Customers(客户表) 和 Orders(订单表) 两张表;
- 表结构合理:列类型对、有主键(Primary Key,用来唯一标记每一行的"身份证")、有外键(Foreign Key,用来保证"订单里的客户ID必须真有其人");
- 数据从 Access/Excel 原样搬过来,且经过对账校验,行数对得上、内容没丢;
- 一套可复用的"AI 提示词 + SQL 模板",下次换张表照抄就行。
三、案例实战:把客户/订单数据迁到 SQL Server
下面按真实操作顺序走。所有 SQL 都是可以直接粘进 SSMS(SQL Server Management Studio,微软官方的数据库管理工具)里执行的。
第一步:装好驱动,打通"读得到源文件"这一关
SSMS 的导入向导本身不认 Access/Excel 文件格式,它要靠一个叫 ACE 驱动(Access Database Engine,微软的"Access/Excel 读卡器")的组件才能读。
- 去微软官网搜"Microsoft Access Database Engine",下载并安装;
- 关键踩坑:ACE 驱动分 32 位和 64 位,关键看导入向导进程的位数——SSMS 自带的"导入和导出数据"向导本身是 32 位进程。所以哪怕你装的是 64 位 Office,也得装 32 位 ACE 驱动,否则向导打不开文件;反过来 32 位 Office 配 64 位 ACE 也会翻车。装之前先看清自己 Office 是 32 还是 64 位,驱动位数跟着"向导进程"走。还有一个经典拦路虎:机器上已装 64 位 Office 时,32 位 ACE 安装包会直接拒绝安装——解决办法是用命令行静默安装(
AccessDatabaseEngine.exe /quiet),或者改走开始菜单里独立的 64 位"SQL Server 导入和导出"向导。
第二步:让 AI(GLM/Kimi)出"建表 SQL 草稿"
别自己硬憋 SQL。把你的 Access/Excel 表结构粘给 ChatGPT,让它翻译成 SQL Server 的建表语句。
可以照抄的提示词:
我有两个 Access 表,请生成 SQL Server 的建表 SQL,并把 Access 类型正确映射成 SQL Server 类型,补上主键和外键,附中文注释。
- Customers(客户表):客户ID 自动编号、客户名称 文本(100)、电话 文本(20)、录入时间 日期/时间
- Orders(订单表):订单ID 自动编号、客户ID 长整型、下单时间 日期/时间、金额 货币、备注 长文本
ChatGPT 一般会吐出下面这样的 SQL(我加了注释,你照着看):
sql-- 客户表:对应 Access 里的 Customers
CREATE TABLE dbo.Customers (
CustomerID int IDENTITY(1,1) NOT NULL, -- 自增主键,对应 Access 的"自动编号(AutoNumber)"
CustomerName nvarchar(100) NOT NULL, -- 客户名称,对应 Access 的"文本(Text)"
Phone nvarchar(20) NULL, -- 电话
CreatedAt datetime NOT NULL DEFAULT GETDATE(), -- 录入时间,对应 Access 的"日期/时间(Date/Time)"
CONSTRAINT PK_Customers PRIMARY KEY (CustomerID) -- 主键:每一行客户的唯一身份证
);
GO
-- 订单表:对应 Access 里的 Orders
CREATE TABLE dbo.Orders (
OrderID int IDENTITY(1,1) NOT NULL, -- 订单号,自增主键
CustomerID int NOT NULL, -- 客户编号,外键,指回 Customers
OrderDate datetime NOT NULL, -- 下单时间
Amount decimal(19,4) NOT NULL, -- 金额,对应 Access 的"货币(Currency)"
Remark nvarchar(max) NULL, -- 备注,对应 Access 的"长文本(Memo)"
CONSTRAINT PK_Orders PRIMARY KEY (OrderID)
);
GO类型映射对照(AI 翻译的核心,记一下):
| Access 里的类型 | SQL Server 里的类型 | 说明 |
|---|---|---|
| 文本 Text(短) | nvarchar(n) |
n 是最大长度,比如 50、100 |
| 长文本 Memo | nvarchar(max) |
max 表示"很长都装得下" |
| 自动编号 AutoNumber | int IDENTITY(1,1) |
自增整数,插数据时自动+1 |
| 数字(整型/长整型) | int |
整数 |
| 货币 Currency | money 或 decimal(19,4) |
金额,四位小数精度更稳 |
| 日期/时间 Date/Time | datetime 或 datetime2 |
日期加时间 |
| 是/否 Yes/No | bit |
只存 0/1(否/是) |
| OLE 对象 / 附件 | varbinary(max) |
二进制,图片附件建议另存文件 |
第三步:在 SSMS 里建库建表
- 打开 SSMS,连上你的 SQL Server 实例(本机一般是
(local)或.); - 在"对象资源管理器"里右键数据库 → 新建数据库,起个名比如
ShopDB; - 点开
ShopDB→ 右键新建查询,把第二步 AI 给的建表 SQL 粘进去,点"执行"。两张空表就建好了。
第四步:用"导入导出向导"把数据搬过来(记得留一份对账副本)
⚠️ 首要原则(务必先看):本案例的
Customers.CustomerID和Orders.CustomerID都是自增列(IDENTITY)。两张表的主外键必须一起保留或一起重排——要么都勾选"启用标识插入"保留源编号,要么都让 SQL Server 重新发号。混着来(比如 Customers 让 SQL Server 重发、Orders 保留旧号)会导致Orders.CustomerID在Customers里找不到对应行,第五步ALTER TABLE ... FOREIGN KEY必失败。下面每一步都按"保留源编号"走,请严格按提示勾选"启用标识插入"。
为了让第六步的 EXCEPT 对账有意义,Orders 要导两份:一份
Orders_Src(原样副本,当"标准答案"),一份正式Orders(业务表)。两份必须保留同样的源 OrderID。
- 在"对象资源管理器"里右键
ShopDB→ 任务 → 导入数据(这就是 SSMS 导入导出向导); - 欢迎页点"下一步";
- 数据源选"Microsoft Access"(Excel 就选"Microsoft Excel"),浏览选中你的
.accdb或.xlsx文件;- 若这里报错"未注册提供程序/找不到驱动",回去检查第一步的 ACE 驱动;
- 目标选 SQL Server(如"Microsoft OLE DB Driver for SQL Server"或"SQL Server Native Client"),服务器名填实例,选
ShopDB; - 选"复制一个或多个表/视图中的数据" → 下一步;
- 导入 Customers:勾选 Customers,点"编辑映射(Edit Mappings)"确认每列类型和建表时一致(比如名称是
nvarchar(100)不是nvarchar(255)),并**勾选"启用标识插入(Enable identity insert)"**保留源 CustomerID(否则 SQL Server 会自动重发新号,与第 8 项 Orders 保留的源 CustomerID 对不上、第五步外键必失败);因为已经建好空表,这里选"追加到现有表" → 下一步 → 立即运行 → 完成。 - 导入对账副本
Orders_Src(创建目标表 + 保留源 OrderID):再跑一次向导(重复 1~5),只勾选 Orders,在映射页选"创建目标表"让向导新建一张Orders_Src,并点"编辑映射"勾选"启用标识插入(Enable identity insert)",把 Access 原来的 OrderID 原样保留 → 立即运行 → 完成。这样Orders_Src就是一份"原汁原味"的源副本。 - 导入正式表
Orders(追加到现有表 + 保留源 OrderID):再跑一次向导(重复 1~5),只勾选 Orders,这次选"追加到现有表"写进第三步建好的Orders,同样点"编辑映射"**勾选"启用标识插入"**保留源 OrderID → 立即运行 → 完成。此时Orders与Orders_Src的 OrderID 完全一致,第六步的 EXCEPT 比对才有意义。
向导本质是微软的 SSIS(SQL Server Integration Services,数据搬运引擎)在后台干活,它把源文件读成"行",再写进目标表。
第五步:补上外键(向导不会自动搬关系)
导入向导只搬"数据",不搬表与表之间的关系。所以迁完得自己补外键,告诉数据库"订单里的客户ID必须能在客户表里找到"。
动手前先确认:Orders 表里每一行 CustomerID 都能在 Customers 表里找到对应记录,否则下面这条 ALTER TABLE 会直接失败(报外键冲突)。可先用
SELECT CustomerID FROM dbo.Orders WHERE CustomerID NOT IN (SELECT CustomerID FROM dbo.Customers)排查。
让 AI(GLM/Kimi)出这段,或自己照抄:
sql-- 迁完数据后,补外键:一个客户可以有多个订单
ALTER TABLE dbo.Orders
ADD CONSTRAINT FK_Orders_Customers
FOREIGN KEY (CustomerID) REFERENCES dbo.Customers(CustomerID);
GO执行后,如果你往 Orders 插了一个不存在的客户ID,SQL Server 会直接拒绝——这就是外键在保数据干净。
第六步:迁移后对账校验
迁完别急着庆祝,先对账。三句话搞定:
sql-- 1) 行数对账:看 SQL 端两张表各多少行
SELECT 'Customers' AS 表名, COUNT(*) AS 行数 FROM dbo.Customers
UNION ALL
SELECT 'Orders', COUNT(*) FROM dbo.Orders;
-- 2) 数据比对:把刚导进来的 Orders 和"源库原样副本 Orders_Src"做差集
-- 有结果 = 两边不一致;空结果 = 一致
SELECT * FROM dbo.Orders
EXCEPT
SELECT * FROM dbo.Orders_Src; -- Orders_Src 是第四步用向导"创建目标表"原样导入的"对账副本",OrderID 与 Orders 一致
-- 3) 抽样肉眼看前 100 行
SELECT TOP (100) * FROM dbo.Orders ORDER BY OrderID;⚠️ 对账铁律:
Orders和Orders_Src这两份副本必须保留同样的源 OrderID(两边都在"编辑映射"里启用标识插入)。一旦某一侧让 SQL Server 重新发号,两边 OrderID 对不上,EXCEPT就会误报"不一致",对账结果作废。
四、原理小结
一句话说清整套迁移在干什么:SSMS 导入导出向导背后是 SSIS 这个"搬运引擎",它把 Access/Excel 源文件按"类型映射表"逐列翻译成 SQL Server 能懂的类型,再一行行写进目标表;所谓"类型映射"就是一份 Access 与 SQL Server 之间的"翻译词典"(文本→nvarchar、自动编号→int IDENTITY、货币→money/decimal(19,4));而主键、外键这些"规矩"属于逻辑层、向导默认不搬,所以得咱们事后用 ALTER TABLE 补上;最后的对账校验,本质是拿 SQL 端的表和源端做"逐行减法"(EXCEPT),差集为空才说明数据一分没少、一字没歪。
五、避坑指南
ACE 驱动位数不匹配:关键看"导入向导进程"的位数——SSMS 自带的"导入和导出数据"向导是 32 位进程,所以即使你装 64 位 Office,也得装 32 位 ACE,否则向导打不开文件;32 位 Office 配 64 位 ACE(或反过来)同样翻车。装之前先确认自己 Office 是 32 还是 64 位,驱动跟着"向导进程"走。
Excel 类型被"前几行"带偏:Excel 导入时,向导默认只看最前面几行来猜这一列是数字还是文本。如果前 8 行都是纯数字、第 9 行突然混进中文,整列就会被误判成数字、后面的文本直接被截成空。解决法:导入时在连接串加
IMEX=1(把整列当文本读),或先把 Excel 存成"文本格式"再导,或干脆经过 Power Query 清洗后再进 SQL Server。向导不搬主键、外键、索引:它只管把数据挪过去,表关系得你用
ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY手动补。漏了这一步,订单里会出现"幽灵客户ID",数据以后越写越乱。自增列(自动编号)导入翻车:SQL Server 的自增列(
IDENTITY)默认不让外部插值。如果你希望原样保留 Access 里的旧编号,在向导"编辑映射"里勾选"启用标识插入(Enable identity insert)";如果你不 care 旧编号、让 SQL Server 重新发号,就把该列从映射里去掉。两张表的主外键要一起保留或一起重排,别一张留旧号一张发新号,否则外键对不上。OLE 对象 / 附件类型会丢或变味:Access 里存的图片、文件附件,向导要么导不进来、要么变成
varbinary(max)的乱码二进制。正经做法是:把附件存到文件夹或对象存储,数据库里只留一个"文件路径"字段。别指望向导帮你把图片搬干净。
六、进阶延展
- 往回补基础:本文的建表、类型、外键都建立在 B13《用 AI 设计第一张 Access 表》、B14《AI 写查询(SQL)不求人》、B15《AI 设计规范化数据库结构》之上。表结构设计、SQL 查询还不熟的话,先回去看这几篇打底。
- 迁完就能接报表:数据进了 SQL Server,就能用 Excel 的 Power Query 连上来做清洗,用 PivotTable(数据透视表) 做汇总,背后就是 SQL 的
JOIN把多张表拼起来;想写更复杂的指标,还能上 DAX(数据分析表达式)。这一脉在 Excel/Power 系列里展开。 - 更大规模的迁移用官方利器:表很多、还要连查询和窗体逻辑时,别硬用向导——微软有免费的 SSMA for Access(SQL Server Migration Assistant),能批量搬 schema(结构)、数据和部分查询,比手点向导稳得多。
- 让 AI 接着帮你:表大了就让 AI 写索引(加快查询)和存储过程(把常用操作存成"一键脚本"),把重复活继续交给 AI。