【数据库】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 让它写,咱们自己把控方向和最后确认。下面用"客户表 + 订单表"这个最常见的一对多关系,带你完整跑一遍。


二、目标产出

跟着做完,你会得到:

  1. 一个 SQL Server 数据库(Express 或任意版本都行),里面有 Customers(客户表)Orders(订单表) 两张表;
  2. 表结构合理:列类型对、有主键(Primary Key,用来唯一标记每一行的"身份证")、有外键(Foreign Key,用来保证"订单里的客户ID必须真有其人");
  3. 数据从 Access/Excel 原样搬过来,且经过对账校验,行数对得上、内容没丢;
  4. 一套可复用的"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 moneydecimal(19,4) 金额,四位小数精度更稳
日期/时间 Date/Time datetimedatetime2 日期加时间
是/否 Yes/No bit 只存 0/1(否/是)
OLE 对象 / 附件 varbinary(max) 二进制,图片附件建议另存文件

第三步:在 SSMS 里建库建表

  1. 打开 SSMS,连上你的 SQL Server 实例(本机一般是 (local).);
  2. 在"对象资源管理器"里右键数据库 → 新建数据库,起个名比如 ShopDB
  3. 点开 ShopDB → 右键新建查询,把第二步 AI 给的建表 SQL 粘进去,点"执行"。两张空表就建好了。

第四步:用"导入导出向导"把数据搬过来(记得留一份对账副本)

⚠️ 首要原则(务必先看):本案例的 Customers.CustomerIDOrders.CustomerID 都是自增列(IDENTITY)。两张表的主外键必须一起保留或一起重排——要么都勾选"启用标识插入"保留源编号,要么都让 SQL Server 重新发号。混着来(比如 Customers 让 SQL Server 重发、Orders 保留旧号)会导致 Orders.CustomerIDCustomers 里找不到对应行,第五步 ALTER TABLE ... FOREIGN KEY 必失败。下面每一步都按"保留源编号"走,请严格按提示勾选"启用标识插入"。

为了让第六步的 EXCEPT 对账有意义,Orders 要导两份:一份 Orders_Src(原样副本,当"标准答案"),一份正式 Orders(业务表)。两份必须保留同样的源 OrderID

  1. 在"对象资源管理器"里右键 ShopDB任务导入数据(这就是 SSMS 导入导出向导);
  2. 欢迎页点"下一步";
  3. 数据源选"Microsoft Access"(Excel 就选"Microsoft Excel"),浏览选中你的 .accdb.xlsx 文件;
    • 若这里报错"未注册提供程序/找不到驱动",回去检查第一步的 ACE 驱动;
  4. 目标选 SQL Server(如"Microsoft OLE DB Driver for SQL Server"或"SQL Server Native Client"),服务器名填实例,选 ShopDB
  5. 选"复制一个或多个表/视图中的数据" → 下一步;
  6. 导入 Customers:勾选 Customers,点"编辑映射(Edit Mappings)"确认每列类型和建表时一致(比如名称是 nvarchar(100) 不是 nvarchar(255)),并**勾选"启用标识插入(Enable identity insert)"**保留源 CustomerID(否则 SQL Server 会自动重发新号,与第 8 项 Orders 保留的源 CustomerID 对不上、第五步外键必失败);因为已经建好空表,这里选"追加到现有表" → 下一步 → 立即运行 → 完成。
  7. 导入对账副本 Orders_Src(创建目标表 + 保留源 OrderID):再跑一次向导(重复 1~5),只勾选 Orders,在映射页选"创建目标表"让向导新建一张 Orders_Src,并点"编辑映射"勾选"启用标识插入(Enable identity insert)",把 Access 原来的 OrderID 原样保留 → 立即运行 → 完成。这样 Orders_Src 就是一份"原汁原味"的源副本。
  8. 导入正式表 Orders(追加到现有表 + 保留源 OrderID):再跑一次向导(重复 1~5),只勾选 Orders,这次选"追加到现有表"写进第三步建好的 Orders,同样点"编辑映射"**勾选"启用标识插入"**保留源 OrderID → 立即运行 → 完成。此时 OrdersOrders_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;

⚠️ 对账铁律OrdersOrders_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),差集为空才说明数据一分没少、一字没歪。


五、避坑指南

  1. ACE 驱动位数不匹配:关键看"导入向导进程"的位数——SSMS 自带的"导入和导出数据"向导是 32 位进程,所以即使你装 64 位 Office,也得装 32 位 ACE,否则向导打不开文件;32 位 Office 配 64 位 ACE(或反过来)同样翻车。装之前先确认自己 Office 是 32 还是 64 位,驱动跟着"向导进程"走。

  2. Excel 类型被"前几行"带偏:Excel 导入时,向导默认只看最前面几行来猜这一列是数字还是文本。如果前 8 行都是纯数字、第 9 行突然混进中文,整列就会被误判成数字、后面的文本直接被截成空。解决法:导入时在连接串加 IMEX=1(把整列当文本读),或先把 Excel 存成"文本格式"再导,或干脆经过 Power Query 清洗后再进 SQL Server。

  3. 向导不搬主键、外键、索引:它只管把数据挪过去,表关系得你用 ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY 手动补。漏了这一步,订单里会出现"幽灵客户ID",数据以后越写越乱。

  4. 自增列(自动编号)导入翻车:SQL Server 的自增列(IDENTITY)默认不让外部插值。如果你希望原样保留 Access 里的旧编号,在向导"编辑映射"里勾选"启用标识插入(Enable identity insert)";如果你不 care 旧编号、让 SQL Server 重新发号,就把该列从映射里去掉。两张表的主外键要一起保留或一起重排,别一张留旧号一张发新号,否则外键对不上。

  5. 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。