ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Access罗斯文数据库实战:表关系、SQL查询与迁移指南

Access罗斯文数据库实战:表关系、SQL查询与迁移指南 简介这是一份以Access内置罗斯文数据库为线索的数据库学习文档面向刚接触Access或数据库设计的新手。罗斯文数据库本身是一个虚构商贸公司的示例库涵盖采购、销售、订单、供应商、客户等典型业务适合通过真实业务场景理解数据库的完整设计流程。文档先从公司业务流程切入讲解表设计思路强调数据分类与表间关联随后逐一介绍文本、备注、数字、货币、自动编号、是/否等数据类型的不同用途以及字段大小、索引、有效性规则等常用属性。针对录入重复信息容易出错的问题还专门说明了查阅列的用法。跟随说明读者能了解如何设计客户表、订单表、订单明细表、产品表等多张表并掌握表与表之间建立关系的方法。资源包内只有1个doc文档大小3.58MB内容集中适合边看边操作。目前已有818人学习对入门者来说是一条直观的学习路径也可作为课堂教学的补充资料。1. 罗斯文数据库是 Access 自带示例里最值得拆开看的进销存第一次打开 Access 自带的罗斯文数据库Northwind时多数人只把它当作一个演示游戏一家叫 Northwind Traders 的虚构食品公司带着客户、订单、库存和采购记录看起来跟真实业务没什么关系。可恰恰是这套随 Access 分发了几十年的示例数据成了无数人学会表关系、SQL 查询、VBA 宏和窗体报表的起点。相比从新建空库开始摸索罗斯文把一套进销存该有的字段、主外键和界面都摆好了你可以直接在里面运行查询、跟读已有窗体甚至把它改造成自己的项目骨架。下面以罗斯文数据库为主线把内部组织、版本定位、练习路径和迁移检查点挨个说清。2. 罗斯文的表关系与数据字典先看清八张核心表2.1 核心八张表之间是怎么连起来的新版罗斯文模板在经典表之外扩充了采购、库存事务等对象但用来理解关系模型的仍然是 Customers、Employees、Suppliers、Shippers、Categories、Products、Orders、[Order Details] 这八张表。它们的关系可以这样概括一张订单Orders有一个客户Customers、一个雇员Employees和一个承运商Shippers订单里每行商品是 [Order Details] 的一条记录指向具体的 Products而 Products 又归到一个 Categories并且有一个 Suppliers 负责供货。Employees 表的 ReportsTo 字段指向本表 EmployeeID是最典型的一对多自引用。在 Access 里打开“数据库工具→关系”会看到这些表之间的连线双击连线能查看是否勾选了“实施参照完整性”。我的建议是先在这里看五分钟再写查询因为后面无论做 SQL 练习还是做迁移主外键关系都是判断结果的依据。看的时候注意 [Order Details] 的主键是 OrderID 加 ProductID 的联合主键而不是单独某个字段——这正是“多对多关系拆成两个一对多”的标准示范。表主键外键/自引用业务含义CustomersCustomerID文本无客户档案EmployeesEmployeeID自动编号ReportsTo → Employees雇员及上下级ProductsProductID自动编号SupplierID、CategoryID供货商品OrdersOrderID自动编号CustomerID、EmployeeID、ShipVia → Shippers订单头[Order Details]OrderID ProductIDOrderID、ProductID订单明细这张表在讲建模时很实用Customers 用文本主键Products 用自动编号主键正好说明主键不一定永远是长整数ReportsTo 又是自外键适合演示递归查询。三句话就能把“一对多”“自引用”“联合主键”讲完不用另外编数据。2.2 先跑通的三句 SQL月份统计、库存预警和产品排行Access 的 SQL 视图在“创建→查询设计→关闭显示表→右键→SQL 视图”里。以下三句可以直接用。先看订单量按月统计SELECT YEAR(OrderDate) AS OrderYear, MONTH(OrderDate) AS OrderMonth, COUNT(OrderID) AS OrderCnt FROM Orders GROUP BY YEAR(OrderDate), MONTH(OrderDate) ORDER BY OrderYear, OrderMonth;这段的要点是YEAR 和 MONTH 是 Access SQL 里可直接使用的函数GROUP BY 后面不能再引用 SELECT 里的别名 OrderYear这与 SQL Server 的行为不同。结果中大约能对应到 1996 到 1998 年间的订单少说也有八百多笔足以跑聚合。接着是库存预警SELECT ProductName, UnitsInStock, ReorderLevel FROM Products WHERE Discontinued False AND UnitsInStock ReorderLevel ORDER BY UnitsInStock;用 而不是 是想把“已经低于警戒线”的商品也查出来Discontinued 是是/否字段在 Access 里可以直接写 False如果将来把语句搬到 SQL Server 上则要改成 0。这是第一个常见的方言差异。最后看产品累计销量SELECT TOP 5 Products.ProductName, SUM([Order Details].Quantity) AS TotalQty FROM Products INNER JOIN [Order Details] ON Products.ProductID [Order Details].ProductID GROUP BY Products.ProductName ORDER BY SUM([Order Details].Quantity) DESC;这里的 Join 对象是 [Order Details]因为表名里带空格必须用方括号包起来。TOP 5 在 Access 中要配合 ORDER BY 才会有确定意义否则它只是“任意的前 5 条”。2.3 为什么说罗斯文是比自建数据更合适的学习样本自建测试数据往往容易做成“字段齐了但逻辑不成立”订单明细没有外键、库存和采购对不上。罗斯文是微软长期维护的完整进销存客户、产品、雇员、供应商、承运商被组织成典型的三层结构客户层、交易层、商品层。用它做演示讲“订单金额为什么要存到明细而不是订单头”“库存预警为什么看的是 ReorderLevel 而不是 0”这类问题直接有现成字段可用。对已经工作多年的人它也有价值当你需要在一个空数据库上快速验证某个 ORM 映射、做一个 BI 报表口径、或者搭一个临时演示环境时罗斯文是少有的同时具备“数据量不大”和“关系足够复杂”两种属性的数据集。数据量小意味着跑得快关系复杂则能暴露出联表时常见的笛卡尔积问题。3. 在本地打开罗斯文模板创建、目录定位和文件格式差异3.1 先试 Access 内置模板文件、新建、搜索 Northwind从 Access 2013 开始示例数据库不再像早期版本那样一定跟着安装盘走更常见的做法是通过模板动态下载。打开 Access 后在“文件→新建→搜索框里输入 Northwind”找到名为“Northwind”的模板点击创建即可。第一次创建会联网下载需要等一会儿创建完成后 Access 会打开一个带导航窗格的完整 accdb 文件里面已经包含了表、查询、窗体、报表和模块。如果你连不上模板库或者公司网络把模板下载地址屏蔽了再从本地安装目录找。用下面这条 PowerShell 命令能快速定位机器上所有名称带 Northwind 的文件Get-ChildItem -Path C:\Program Files\Microsoft Office -Recurse -Filter Northwind* -ErrorAction SilentlyContinue | Select-Object FullName这条命令会遍历 Office 安装目录下的子目录按文件名前缀找出 Northwind.accdb 或 Northwind.mdb最后输出完整路径。-ErrorAction SilentlyContinue 的作用是跳过没有权限访问的目录避免中断整个查找过程。如果命令没结果还可以把 -Path 换成整个 C 盘但时间会更长。3.2 不同 Office 版本的典型路径和文件名下面是常见情况具体路径以本机安装版本为准Office 版本常见位置文件名格式Access 2003/2007C:\Program Files\Microsoft Office\OFFICE11 或 OFFICE12\SAMPLESNorthwind.mdbmdb 经典八表Access 2010C:\Program Files\Microsoft Office\OFFICE14\SAMPLESNorthwind.accdb 或 Northwind.mdb视安装而定Access 2016/2019/2021C:\Program Files\Microsoft Office\root\Office16\SAMPLESNorthwind.accdbaccdb 扩展版文件名后缀决定了你能做什么.mdb 是 Access 2003 之前的格式新版 Access 打开它时会进入兼容模式VBA 里涉及 Windows API 的声明可能需要加 PtrSafe 才能编译.accdb 是 2007 年之后的主格式支持附件、多值字段和数据宏但不能被老版本 Access 直接打开。如果你看到的那份材料叫“罗斯文数据库.doc”要意识到它通常是说明文档或培训材料真正能打开并运行的是 .mdb/.accdb 文件不能把 Word 文档直接改后缀当数据库用。3.3 打开之后先调的三处设置第一次打开罗斯文Access 会显示“安全警告已禁用应用程序的某些内容”。这是宏和 VBA 代码被禁用的提示不点“启用内容”的话很多示例窗体背后的代码不会运行表现就是按钮点了没反应。如果你不希望每次都弹这个警告把数据库所在目录加进“文件→选项→信任中心→受信任位置”即可。另外两处建议一并检查一是“文件→选项→客户端设置→默认文件格式”如果团队还维护着旧版 mdb 数据库把它设成较早的格式能减少误存新格式的机会二是导航窗格是否显示所有对象在导航窗格上右键→“导航选项”把“显示系统对象”也勾上。勾选后你能看到类似 MSysObjects 这样的系统表排查链接表问题时用得到。4. 拿罗斯文练 SQL、VBA 和窗体记录源一条练习路径4.1 参数查询体会 Access 的参数提示学 Access 数据库时最常用到的是参数查询罗斯文里有大量字段可以用来做“按日期范围查订单”“按最低金额筛客户”的练习。下面这句是查单笔订单金额超过指定值的订单PARAMETERS [最低销售额] Currency; SELECT [Order Details].OrderID, SUM([Order Details].UnitPrice * [Order Details].Quantity * (1 - [Order Details].Discount)) AS Total FROM [Order Details] GROUP BY [Order Details].OrderID HAVING SUM([Order Details].UnitPrice * [Order Details].Quantity * (1 - [Order Details].Discount)) [最低销售额];PARAMETERS 语句在整个 SELECT 之前用来声明一个名为“最低销售额”的 Currency 参数。运行查询时会先弹窗要求输入参数值适合在课堂上演示“同样一条查询不同参数得到不同结果”。HAVING 是对分组后的结果过滤不能换成 WHERE因为聚合函数发生在分组这一步之后。这里值得注意 [Order Details] 里的 UnitPrice、Quantity 和 Discount折扣是小数比如 0.15 表示 85 折计算时用的是 1 - Discount。4.2 用 VBA DAO 读订单理解对象模型在 VBA 里读罗斯文最直接的方式是 DAO。按 CtrlG 打开立即窗口新建一个模块粘贴下面的过程Public Sub PrintTopOrders() Dim db As DAO.Database Dim rs As DAO.Recordset Dim sql As String Set db CurrentDb() sql SELECT TOP 5 OrderID, CustomerID, Freight _ FROM Orders ORDER BY Freight DESC; Set rs db.OpenRecordset(sql) Do While Not rs.EOF Debug.Print rs!OrderID, rs!CustomerID, rs!Freight rs.MoveNext Loop rs.Close Set rs Nothing Set db Nothing End SubCurrentDb() 返回当前 accdb 的连接句柄所有查询都从它开启OpenRecordset 是 DAO 里最常用的方法第二个参数如果不写默认按动态集类型打开。循环里用 rs!OrderID 的惊叹号语法读取字段比 rs.Fields(OrderID) 短rs.MoveNext 用于推进游标千万不能漏否则会死循环。输出会出现在立即窗口里按 CtrlG 可见。这段代码虽然短但演示了 Access 开发最核心的套路SQL 负责取数DAO 负责遍历Debug.Print 负责输出。把 SELECT 换成更新语句时要注意DAO 默认不会隐式提交需要在事务里显式用 db.BeginTrans 和 db.CommitTrans。4.3 把窗体的 RecordSource 当成 SQL 入口在罗斯文的导航窗格里随便打开一个订单窗体切到“设计视图”再按 F4 打开属性表展开“数据”选项卡能看到一个名为“记录源”的属性。它既可以是一个表名也可以是一段 SELECT 语句。直接改成上面 4.1 的查询窗体马上就会只显示符合条件的订单这是理解“窗体就是数据的一个视图”最快的方法。进一步可以打开罗斯文自带的客户订单窗体看它的子窗体是如何通过 LinkMasterFields 和 LinkChildFields 与主窗体关联的。这两个属性填的是主键和外部键的字段名Access 在运行时根据主窗体当前行的取值去刷新子窗体的记录源。这种联动方式就是后来很多人做 C/S 或 B/S 界面时手动写关联查询的前身。5. 跑罗斯文时最常踩的 4 个坑驱动、路径、通配符和空值5.1 64 位系统上的 OLE DB Provider 找不到用代码连接 accdb 文件时最常见的是这句连接串ProviderMicrosoft.ACE.OLEDB.12.0;Data SourceC:\Northwind\Northwind.accdb;Persist Security InfoFalse;在 64 位 Windows 上如果只装了 32 位 Access这个 Provider 只在 32 位进程里注册。默认用 AnyCPU 编译的 .NET 程序会以 64 位进程运行于是报“未在本地计算机上注册 Microsoft.ACE.OLEDB.12.0 提供程序”。这跟代码本身无关纯粹是位数不匹配。两个解决办法一是把 .NET 项目的“目标平台”改为 x86让程序以 32 位进程去访问同一个 Provider二是安装 64 位版 Microsoft Access Database Engine 可再发行组件但注意它和 32 位 Office 不能共存装了 Office 32 位就别指望再装 64 位引擎。我的经验是先确认 Office 位数再看把程序编成 x86 还是换驱动两个方向任何一边都能解决问题最怕两边都动。5.2 数据库放同步盘导致 .laccdb 锁文件写不进去Access 打开 accdb 时会在同目录生成一个以 .laccdb 结尾的锁文件用于记录哪些用户正在使用数据库。把这个文件放进 OneDrive、坚果云这类同步目录时文件被后台程序不断盯住Access 可能报“无法创建锁定文件”或“文件正在使用”。这并不是 Access 本体的错误而是同步软件对文件锁的干扰。解决方式是把数据库移到本地固定目录或共享文件夹并为共享用户设置一致的“打开模式”。具体在“文件→选项→客户端设置→高级”里把“默认打开模式”设为“共享”避免多人同时访问时进入互斥状态。如果必须放在同步盘至少要对全库执行“压缩和修复数据库”后再上传能减少一些低版本的副本问题。5.3 通配符和日期常量不是同一个字符Access 的查询设计器默认使用 ANSI-89 通配符匹配字符写例如 Like A而在 ADO、ODBC 直通查询或链接的 SQL Server 表里通配符是 %。我见过不少人把 Access 里写好的查询直接粘到后台数据库里执行结果什么都查不到。下面是一组对照-- Access 查询或 VBA 的 DAO 环境 WHERE CustomerID LIKE A*; -- ODBC 直通查询、链接 SQL Server 表 WHERE CustomerID LIKE A%;日期常量也一样。Access 里正确的写法是 #2024-01-01#单引号包住的 2024-01-01 会被当成字符串在很多比较场景里不会报错但结果不对。这个坑尤其容易出现在把罗斯文数据迁到 SQL Server 后原来的查询文件保留在 Access 前端里直通执行时爆出来。5.4 NULL 与零长度字符串两个不同的“没有”罗斯文不少字段允许为空ShipRegion 就是典型。WHERE ShipRegion Is Null只能查出从未填过值的行查不出被设为空字符串的行反过来WHERE ShipRegion 也查不到 NULL。“是 Null / 零长度字符串 / 有内容”在 Access 里是三态而不是两态。Access 表设计视图里有一个“允许零长度字符串”属性默认是“否”一旦打开它空字符串就能写入文本字段这时前面说的三态问题就会出现。对这种字段做统计报表时我习惯先统一口径要么在写入层禁止空字符串只保留 NULL要么在 SQL 里用Nz(ShipRegion, )把 NULL 归并成空串再分组。不同时处理这两个状态报表里同一个客户可能被拆到两行。6. 把罗斯文迁到 SQL Server 时的 5 条检查项把一个 Access 示例库迁到 SQL Server不等于“导出成功了”就完事后面还有类型映射、查询改写和前端链接三个环节。下面 5 步是我在类似迁移里固定执行的动作。第一步先修数据。在 Access 里执行“数据库工具→分析性能”和关系窗口的完整性检查确保每张表都有主键联合主键的表没有重复行。罗斯文本身很干净但如果之前在里面存过你的测试数据这步能省去后面导入一半报错再回滚的麻烦。第二步选迁移工具。老版本 Access 的“升迁向导”在现在的版本里不再默认提供推荐用 SSMA for Access 或“外部数据→新建数据源→从数据库→SQL Server”。只使用外部数据向导时表结构和索引能建好但视图和模块要手动处理SSMA 则能把查询转为视图更适合整体迁移。第三步核对类型映射。下表是罗斯文里最容易出问题的一组对应关系Access 类型SQL Server 默认类型注意点文本255nvarchar(255)字符集按排序规则走中文一般没问题是/否bit代码里 False/True 要改成 0/1日期/时间datetime2(0)Access 的 Date 精度本身不高OLE 对象varbinary(max)迁移后可能无法直接用 Access 显示自动编号int identity必须保留种子和增量第四步改 SQL。把 Access 方言改成 T-SQL#2024-01-01#换成2024-01-01Like 里的*换成%Is Null保持原样NZ()换成ISNULL()。罗斯文里的查询窗体很多我一般先在 Access 里把所有查询导出成文本再批量替换。第五步前端保持不变。把 SQL Server 的表作为链接表导入 Access用户继续用原有窗体底层数据已经落到后端。此时要注意“链接表管理器”里每条链接都指向新的 ODBC DSN避免一端连接成功另一端连不上。验证方式很简单在 VBA 里执行SELECT COUNT(*) FROM Orders如果返回的数值跟 Access 原库一致迁移链路就通了。本文还有配套的精品资源点击获取
返回列表