简介:中财ACCESS数据库复习题.docx是一份面向ACCESS数据库课程学习与考前复习的要点与题库资料,覆盖数据库三级模式结构、关系模型完整性约束、并发控制、实体间联系、SQL选择投影联接操作、规范化及E-R模型转换等核心概念,也包含针对具体数据表的SQL查询、视图创建、记录更新等典型题型。资源内为1个docx文档,共23KB,文字版便于直接打印、批注或导入笔记软件。包内系统梳理了填空题知识框架,从主键选取、INSERT INTO插入记录到DROP TABLE删表、SUM/MIN/COUNT函数用法均有涉及;同时给出多道选择题的标准答案与解析,有助于快速定位易混淆概念(如BETWEEN边界判定、SELECT MAX数组存储位置等),适合需要集中回顾知识点的学生考前自测与查漏补缺。该文档目前已获得67人次的浏览学习,可作为ACCESS基础教学或期末复习的辅助材料。
1. 一份ACCESS数据库复习题,为什么值得拆开讲
这套中财《数据库及应用》复习题,表面上是一份期末备考资料,实际上把Access数据库从概念到实操的考点全串了一遍:三级模式、完整性约束、SQL查询、视图、DAO记录集操作,几乎每道题都在考“能不能动手”。我拆完以后的感觉是,它比很多教材的课后题更贴近真实办公场景——比如给你一个股票表,让你排序、分组、更新单价,这些操作放到企业里就是报表和批量数据处理。
对两类人尤其有用:一类是正在考Access或数据库基础课程的学生,另一类是工作中要接手Access数据库维护的工程师。前者需要把概念和SQL对应起来,后者需要知道记录集怎么遍历、怎么避免空指针和重复主键。这篇文章不贴原题答案,而是把每类题背后的原理、语句边界和容易翻车的细节展开,你可以拿它当复习提纲,也可以当Access + SQL的速查手册。
2. 从三级模式到完整性约束:先把理论基础夯实
2.1 外模式、概念模式、内模式到底对应数据库的哪一层
复习题第一题问的就是三级模式结构:外模式、概念模式(也叫模式)、内模式。这是数据库系统的逻辑分层,初学者容易混淆,因为Access里没有直接暴露这三个概念。
- 外模式对应视图(VIEW),是用户看到的数据窗口,可以隐藏字段、限制行;
- 概念模式对应整张表的逻辑结构,比如“学生表”有哪些列、主键是什么;
- 内模式对应物理存储,比如Access里.accdb/.mdb文件在磁盘上的组织方式。
Access是一个自带图形界面的关系型数据库,通常你建表、建查询,操作的是概念模式和外模式。视图就是典型的外模式,下面这个语句在Access里创建了一个只含深圳交易所股票的视图:
CREATE VIEW stock_view AS SELECT * FROM stock WHERE 交易所="深圳";执行后视图里只有深发展、深万科两条记录。视图本身不存数据,它的行和列来自基表stock,所以对视图查询时,引擎会去读原表。这也是为什么题里考“视图对应外模式”,因为视图给用户暴露的正是经过筛选后的数据视图。
2.2 实体完整性靠主键,参照完整性靠外键,用户自定义完整性靠规则
关系模型的三类完整性约束中,实体完整性要求主键不能为NULL,且不能重复;参照完整性要求外键要么为NULL,要么等于被引用表的主键;用户自定义完整性是业务规则,比如年龄必须大于0。
在Access里写SQL建表时,这些约束是这样落地的:
CREATE TABLE 学生表 ( sno TEXT(10) PRIMARY KEY, sname TEXT(8) NOT NULL, ssex TEXT(1), sage INTEGER, sdept TEXT(20) );这里sno作为主键,自动满足实体完整性。NOT NULL是用户自定义完整性约束的简单例子——不许为空。如果你再建一个修课表,用外键指向学生表:
CREATE TABLE sc ( sno TEXT(10) NOT NULL, cno TEXT(6) NOT NULL, grade INTEGER, PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES 学生表(sno) );注意Access的SQL语法中,REFERENCES需要在查询设计视图的SQL模式下执行,而且两表都要保存在同一个数据库文件中。这个外键约束确保你插入sno='9999'的修课记录时会被拒绝,因为学生表里没有这个学号。
2.3 一对一到多对多:关系类型决定表结构怎么拆
“一个公司只能有一个总经理”“一个员工可以参与多个项目,一个项目也可以有多个员工”……这类题考的是实体间的联系类型。关系类型直接影响表的设计:
- 一对一:可以把两个实体的主键合并成一张表,或者把一方的主键作为另一方的外键并加唯一约束;
- 一对多:在“多”的一方添加外键,例如订单表里放“客户号”;
- 多对多:必须拆成三张表,中间表存两个外键。
回到复习题,班级和班长是一对一,因为一个班只有一个班长、一个班长只对应一个班。职工和部门是一对多,所以“部门号”放在职工表里,而不是反过来。多对多比如“学生-课程”就要建中间表sc,联合主键(sno, cno)。
3. SQL 查询与操作:选择、投影、连接和更新一次说清
3.1 SELECT 的执行顺序与排序陷阱
复习题第1题是SELECT * FROM stock ORDER BY 单价,答案选“升序排列”。很多人疑惑为什么不是降序,因为ORDER BY默认升序(ASC),降序要加DECS。这个考点背后是SQL子句的执行顺序:先FROM,再WHERE,再GROUP BY,再HAVING,再SELECT,最后ORDER BY。所以ORDER BY里可以使用SELECT中的别名,但不能在WHERE里用别名。
实操时,排序通常伴随Top N。比如“工资最高的前十名”:
SELECT TOP 10 * FROM 职工 ORDER BY 基本工资+职务津贴 DESC;这里TOP 10是Access特有的写法,SQL Server也支持,但MySQL用LIMIT。注意TOP 10必须和ORDER BY一起用才有意义,否则随机取10条。另外Access的TOP支持PERCENT,比如TOP 10 PERCENT等价于TOP 10%,但语法是TOP 10 PERCENT,不是TOP 10%。
3.2 WHERE 与 BETWEEN:含边界与不含边界的区别
题目里单价 BETWEEN 12.76 AND 15.20等价于单价>=12.76 AND 单价<=15.20。BETWEEN是闭区间,包括两端值。这个点很基础,但考试喜欢反着考“以下哪个等价”,实际工作中也容易踩:如果你要查询一个开区间,比如不下于12.76但不超过15.20,就要写> AND <,千万不能套BETWEEN去改边界。
通配符也是Access SQL的重灾区。Access里LIKE "A*",星号代表任意多个字符,问号代表单个字符,而SQL Server用的是百分号%和下划线_。这个差异在从Access迁移到其他数据库时经常导致查询结果为空。复习题第13题就是考这个:
DELETE FROM 图书 WHERE 图书号 LIKE "A*";Access中删除记录用DELETE FROM,但不是真正物理删除,只是加删除标记,压缩数据库后才彻底删除。而DROP TABLE是删表结构,完全不同。
3.3 分组统计:GROUP BY 与 HAVING 的配合
“求每个交易所的平均单价”必须按交易所分组,而不是按单价分组。正确写法是:
SELECT 交易所, AVG(单价) FROM stock GROUP BY 交易所;如果题目要求“统计每个部门的平均年龄,只取前3个”,并且要降序排列,需要用HAVING吗?不需要,只要GROUP BY + ORDER BY + TOP:
SELECT TOP 3 部门号, AVG(年龄) AS 平均年龄 FROM 职工 GROUP BY 部门号 ORDER BY AVG(年龄) DESC;这里有个细节:Access的ORDER BY中不能直接用别名“平均年龄”,有的版本可以,但保险起见还是用表达式。HAVING用在分组后过滤,例如“订单数在3个以上且平均金额在200元以上”:
SELECT 职员号 FROM 订单 GROUP BY 职员号 HAVING COUNT(*)>3 AND AVG(金额)>200;注意WHERE过滤行,HAVING过滤组。如果 WHERE 和 HAVING 同时出现,先执行WHERE,再分组,再HAVING。这是高频考点。
3.4 子查询与聚合:WHERE 中使用聚合函数
题目问“单价等于最低单价的记录”,不能直接在WHERE里写MIN(单价),必须用子查询:
SELECT 股票代码, 单价 FROM stock WHERE 单价 = (SELECT MIN(单价) FROM stock);Access支持在WHERE后跟一个返回单值的子查询。如果子查询返回多行,要用IN。统计“最低价的记录个数”,根据题数据,最低价7.48有两条记录(青岛啤酒和深发展),所以结果记录个数是2。
子查询还可以用在NOT IN排除场景,比如“没有签订任何订单的职员”:
SELECT 职员号, 姓名 FROM 职员 WHERE 职员号 NOT IN (SELECT 职员号 FROM 订单);性能上,这种写法在数据量小时没问题,但职员工资表几万行时建议改成LEFT JOIN ... IS NULL,效果一样,执行计划更优。
3.5 INSERT、UPDATE、DELETE 与 ALTER TABLE:写操作比查询更容易出问题
INSERT有两张常见形式。一种是向指定列插入:
INSERT INTO 学生表(sno, sname, ssex, sage, sdept) VALUES ('1001','张小和','男',39,'财经系');另一种是从表查询插入另一张表:
SELECT 学号, 姓名 INTO 优秀学生 FROM 学生 WHERE 高考成绩 > 600;这个SELECT INTO在Access里会创建新表“优秀学生”,但如果表已存在会报错,需要先删除。
UPDATE不用多说,最容易错的是忘了WHERE条件。比如“所有单价上浮8%”:
UPDATE stock SET 单价 = 单价 * 1.08;而“职称为高级工程师的津贴加200”:
UPDATE 职工 SET 职务津贴 = 职务津贴 + 200 WHERE 职称 = '高级工程师';DELETE也一样,不带WHERE就是清空表。而“删除表”用DROP TABLE,不是DELETE。题目里“删除表stock”唯一正确命令是DROP TABLE stock。
ALTER TABLE在Access里的语法略有不同。增加字段:
ALTER TABLE 部门 ADD 单位所在地 TEXT(20);删除字段:
ALTER TABLE 部门 DROP COLUMN 单位所在地;注意Access用DROP COLUMN,不要写成DROP 单位所在地。新增记录直接用INSERT。字段类型TEXT对应文本,日期要用DATETIME,整型是INTEGER或LONG。实际操作中,我习惯先用查询设计视图的“数据表视图”确认字段类型,再写ALTER,否则类型不匹配容易把已有数据截断。
4. Access 对象与 DAO 记录集:窗体背后的数据流动
4.1 七个对象里,报表是唯一不依赖数据文件的对象吗
Access数据库对象有七种:表、查询、窗体、报表、数据访问页、宏、模块。复习题说“除报表外,其他对象都存放在.MDB文件里”,这句话容易误解。实际上,在.accdb格式中,所有对象(包括报表)都存在数据库文件中,报表只是不直接存储数据,它的数据源来自表或查询。早期版本里报表可以在独立文件里,但现代Access统一管理。这题更准确的理解是:报表的数据来源是查询或表,它本身不是数据容器。
表是存储数据的根本,查询是动态数据集合,窗体是人机交互界面,报表用于打印输出。宏和模块是自动化逻辑。数据访问页在较新版本中已不再支持,旧版是网页形式。
4.2 用 DAO.Recordset 遍历记录,比 DLookup 更可控
复习题末尾给出了第10章的VBA代码,通过DAO操作“读者注册表”。核心流程是:声明DAO.Database和DAO.Recordset,然后在Form_Load里打开数据库和记录集。这段代码值得细看的是循环遍历和增删改的写法。
Dim db As DAO.Database Dim rst As DAO.Recordset Private Sub Form_Load() Set db = DBEngine.Workspaces(0).Databases(0) Set rst = db.OpenRecordset("读者注册表", dbOpenDynaset) End SubDBEngine.Workspaces(0).Databases(0)指的是当前Access数据库。如果你想打开外部数据库,需要先OpenDatabase,例如DBEngine.Workspaces(0).OpenDatabase("C:\data\library.accdb")。
遍历记录集判断是否重复,用的是rst.MoveFirst+Do While Not rst.EOF,其中EOF表示文件尾。这是最经典的遍历模式。如果记录集只有一行,也要先判断BOF And EOF都为真——这代表空记录集。
添加记录的标准动作是AddNew→ 给字段赋值 →Update。这段代码里有个细节:ent = MsgBox(...),如果用户点击“取消”,就执行CancelUpdate,不会写入数据库。这是事务思想的雏形。
rst.AddNew rst("读者ID") = txt1.Value rst("姓名") = txt2.Value rst("证件号码") = txt3.Value rst("注册日期") = txt4.Value rst("联系方式") = txt5.Value rst.Update注意字段名必须和表里完全一致,否则会报“找不到字段”。代码里用txt1.Value而不是txt1.Text,是因为当文本框失去焦点后,Value才能正确获取内容,Text只能在焦点期间读取。
4.3 查找、编辑、删除记录:游标移动的常见误区
查找功能里,db.OpenRecordset(strsql)创建了一个新记录集,rst1.EOF用来判断是否存在记录。如果找到多条,代码用MsgBox询问“查找是否正确”,点“否”就MoveNext继续找。这个逻辑有一个问题,当循环到EOF时,没有退出循环,可能会陷入无限循环——实际代码里Do While Not rst1.EOF会在EOF时退出,但如果用户一直点“否”,到最后一条后循环结束,也不会崩溃。更健壮的写法是加一个标志位。
编辑记录使用Edit和Update组合,删除使用Delete。Delete之后,记录指针会指向已删除的位置,必须移动指针才能继续操作。代码里删除后直接MoveFirst,这没问题,但如果记录集为空,MoveFirst会报错,需要先判断BOF And EOF。
移动记录的四个按钮:首记录、上一记录、下一记录、尾记录。题目代码里cmd2_Click重复出现了两次,一次是“查找”,一次是“首记录”,这是因为原题排版有误。实际编写VBA时,注意按钮的Click事件不能重复定义,否则编译错误。
Private Sub cmdFirst_Click() rst.MoveFirst Call ShowData End Sub Private Sub cmdNext_Click() If rst.EOF Then MsgBox "已到最后一条" Else rst.MoveNext Call ShowData End If End Sub这里的ShowData是一个自定义过程,把当前记录的字段值塞到文本框里。这样主逻辑清晰,避免在每个事件里重复写赋值代码。
5. 易错点与刷题技巧:把复习题当面试题来做
5.1 五个高频易错点速查
下面是复习题里最容易出错的几个点,也是Access开发中常见的坑,整理成表方便对比:
| 场景 | 正确做法 | 常见错误 |
|---|---|---|
| 降序取前几条 | ORDER BY 字段 DESC | 忘了DESC,默认升序 |
| 空值判断 | WHERE 字段 IS NULL | 写字段 = Null,永远为假 |
| 删除表 | DROP TABLE 表名 | 用DELETE FROM |
| 视图对应层次 | 外模式 | 写成模式或内模式 |
| 多表分组 | 按关联字段分组 | 按非分组列分组导致语法错误 |
另一个高频点是COUNT(*)与COUNT(列名)的区别。COUNT(*)统计所有行,包括NULL;COUNT(列名)跳过NULL。题里问“非空值的个数”,必然用COUNT(字段名),如果字段是主键,两者相同。
5.2 用查询设计视图对照SQL,比死记硬背有效
Access的查询设计视图(QBE)会自动生成SQL,这是刷题时最好的自检工具。你可以把题目要求的查询用QBE拖出来,然后切换到SQL视图看Access生成的语句,再对比标准答案。比如创建一个统计每个系女生人数的查询:
- 在“创建”选项卡里选“查询设计”;
- 添加“学生”表;
- 双击“所在系”和“学号”字段;
- 在“总计”行把“学号”改为“计数”;
- 在“所在系”条件列输入
"女"; - 运行后切到SQL视图,会看到类似:
SELECT 学生.所在系, Count(学生.学号) AS 学号之计数 FROM 学生 WHERE (((学生.性别)="女")) GROUP BY 学生.所在系;这个过程中,你能直观理解GROUP BY和WHERE的位置关系。如果自己手写SQL写错了,比如把WHERE写到GROUP BY后面,QBE会拒绝执行,这时再对照生成的正确语句改,印象更深。
5.3 一个能直接照抄的 VBA 数据遍历模板
最后分享一个在实际Access维护中常用的数据导出模板。当你需要把表中符合条件的数据批量处理到Excel或文本文件时,这段代码比DoCmd.TransferSpreadsheet更灵活:
Sub ExportData() Dim db As DAO.Database Dim rst As DAO.Recordset Dim fso As Object, ts As Object Dim sql As String Set db = CurrentDb sql = "SELECT * FROM 职工 WHERE 基本工资>3000" Set rst = db.OpenRecordset(sql, dbOpenSnapshot) Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.CreateTextFile("D:\export.txt", True) Do While Not rst.EOF ts.WriteLine rst!职工号 & "|" & rst!姓名 & "|" & rst!基本工资 rst.MoveNext Loop ts.Close rst.Close db.Close Set rst = Nothing Set db = Nothing End Sub这里dbOpenSnapshot表示静态快照,适合只读查询;如果需要更新数据,用dbOpenDynaset。写文件用Scripting.FileSystemObject,分隔符用竖线,避免数据里含逗号或制表符时Excel解析错乱。这段代码不需要额外引用,Access内置。把它放在标准模块里,点击运行就能在指定路径生成文本文件。
本文还有配套的精品资源,点击获取