
简介《软件工程课程设计指导书》面向计算机科学与技术等专业的软件工程初学者服务于课程设计实践环节帮助读者把面向对象方法、C语言与数据库知识落到一个小型软件系统的完整开发过程中。文档以选课系统为案例串联需求分析、软件设计、软件测试到源码提交的全流程明确登录、选课、退课、成绩查询等功能要求以及用例图、序列图、对象模型、状态图等文档产出规范并给出书面报告的结构与成绩考核构成。附录补充了用 ODBC 建立数据源、C Builder 6.0 窗体搭建与 ADO 连接数据库的操作指引可视为一份从建库到连库的起步路线。资源包共 1 个 doc 文件约 539KB轻量易取适合在 10 学时上机中对照执行或作为报告撰写参照。目前已有 99 人学习可供刚接触软件工程规范、需要按步骤完成课程设计的学生参考。1. 先看清这份软件工程课程设计指导书10 学时里真正要交付什么很多同学拿到《软件工程课程设计指导书》的第一反应是照着附录拖窗体真正让课程设计卡住的往往不是控件而是需求字段、数据源和测试序列三件事对不上。这份软件工程指导书围绕一个选课系统把 10 学时上机拆成需求、设计、编码、测试和报告五段技术栈锁定 C Builder 6.0 加 Access 2000先修课要求一门高级语言、C 和数据库系统概论。它适合计算机相关专业做课程设计的学生也适合需要快速复盘传统 C/S 开发流程的初级开发者。资源不是可以直接交差的完整源码而是一份带操作指南的实践任务书字段至少覆盖哪些、功能至少做哪几个、报告里必须出现哪些图都写在任务里。把它当成验收清单用比当成教程从头读到尾更有效。2. 需求与数据模型把选课系统拆成 5 张表和 4 类图这一章先把“画图”往后放先冻结对象和字段。指导书里的功能要求看起来只有登录、查询开课、查询选课、查询成绩、选课、退课但字段清单很长学生、教师、课程、开课、成绩混在一起。如果不先拆表后面画用例图时会把“选课”画成一次数据库插入序列图也会变成一堆没有生命线的箭头。常见的翻车点不是代码写不出来而是报告里的对象模型和数据库表对不上答辩时被追问一句“选课记录存在哪张表”就答不圆。我一般会先做名词筛选学生、教师、课程、开课计划、选课记录这五个名词能覆盖指导书列出的全部字段。学生和教师是人员对象课程是教学计划对象开课计划是某学期某教师在某教室开某门课选课记录是学生和开课计划之间的关联对象。成绩不单独建表平时成绩、考试成绩、总评成绩挂在选课记录上这样查询成绩时不用跨三张表。开课计划里的“选课人数”是冗余字段写入时维护查询时可以直接显示不必每次 count。这个取舍在单机 Access 场景下很实用代价是必须用事务保证人数和选课记录一致。2.1 先冻结五个对象学生、教师、课程、开课、选课记录对象模型不需要画得很花但每个对象要有主键和关键属性。学生对象的主键用学号教师对象用教师号课程对象用课号开课计划用自动编号的开课号选课记录用自动编号的选课号。选课记录上保留学生学号和开课号作为外键再加平时成绩、考试成绩、总评成绩。这样对象模型和后面的 Access 表可以一一对应报告里的类图不会变成“学生类里有课程列表、课程类里又有学生列表”的循环。对象主键关键属性说明学生学号姓名、密码、性别、出生年月、籍贯、地址、电话、家庭地址登录和选课的主体教师教师号姓名、教研室、职称、性别、电话开课和录入成绩的主体课程课号课名、学分、先行课号、课时课程目录先行课号自关联开课计划开课号课号、教师号、开课教室、人数限制、选课人数某次具体开课选课记录选课号学号、开课号、平时成绩、考试成绩、总评成绩学生与开课计划的关联这张表的作用是让报告里的对象模型有落点。画用例图时学生参与者触发登录、查询开课、选课、退课、查询成绩教师参与者触发录入成绩、查询开课名单教务管理员参与者维护课程和开课计划。指导书没有明确写管理员但开课数据总得有人维护常见做法是教师兼维护或者单独设一个管理角色。角色数量不要求多关键是每个用例都能在对象模型里找到承载表。2.2 字段清单落到 Access 表类型、主键和唯一索引Access 2000 的字段类型不多文本、数字、日期/时间、货币、备注、是/否够用。学号用文本 12 位不要用数字否则前导零会丢教师号文本 8 位课号文本 8 位姓名文本 20 位密码文本 32 位课程设计可以存明文但报告里要写清风险合格做法是客户端先做一次哈希再入库电话文本 20 位地址和家庭地址用文本 50 位或备注出生年月用日期/时间学分、课时、人数限制、选课人数用数字字段大小选整型成绩用数字字段大小选单精度或双精度保留一位小数。选课表要加唯一索引索引字段是学号加开课号。这个索引不是可选项它是防止同一学生重复选同一门课的最后一道闸。开课表的选课人数要有默认值 0人数限制要有验证规则0。课程表的先行课号允许为空表示没有先行课如果不为空插入前要检查先行课是否已经修过课程设计可以只做提示不必强制阻断。总评成绩建议存下来Access 2000 没有计算列查询时再算会让报表和界面各写一套公式后面改权重很容易漏改。表字段示例类型建议约束学生表学号、姓名、密码、性别、出生年月、籍贯、地址、电话、家庭地址文本/日期学号主键密码非空教师表教师号、姓名、教研室、职称、性别、电话文本教师号主键课程表课号、课名、学分、先行课号、课时文本/数字课号主键先行课号可空开课表开课号、课号、教师号、开课教室、人数限制、选课人数自动编号/文本/数字课号、教师号外键人数限制大于 0选课表选课号、学号、开课号、平时成绩、考试成绩、总评成绩自动编号/文本/数字学号加开课号唯一索引字段名可以用英文缩写也可以用拼音报告里要有一张字段对照表。不要用Name、Password这种保留字或过于通用的名字Access 查询里容易加方括号。密码字段不要叫Pwd又在界面里显示成“密码”报告里写清楚是登录密码。成绩字段允许为空表示还没录入查询时要区分“0 分”和“未录入”否则总评统计会把未录入当零分。2.3 用例图与序列图把“选课成功”画成可检查的步骤用例图不是把功能名堆成椭圆就完事。学生参与者连到登录、查询开课、选课、退课、查询成绩教师参与者连到录入成绩、查询开课名单管理员参与者连到维护课程、维护开课计划。每个用例下面可以用备注写前置条件比如选课的前置条件是已登录、未重复选课、人数未满。用例图里不要出现“数据库”这种系统内部对象参与者只写人或者外部系统。序列图至少画两条登录成功和选课成功。登录序列的生命线是登录界面、登录控制器、学生表消息顺序是输入学号密码、参数化查询、返回学生记录、打开主界面。选课序列的生命线是选课界面、选课服务、开课表、选课表消息顺序是提交学号和开课号、检查重复、检查容量、插入选课记录、更新选课人数、返回结果。序列图里要把“事务开始”和“事务提交”画进去不画的话报告看起来像没有并发控制的单机玩具。画序列图时每个消息名用动词加名词比如checkCapacity(offeringId)、insertEnrollment(sno, offeringId)、updateSelected(offeringId)。不要写处理选课这种大颗粒消息评审时看不出步骤。指导书要求报告里有序列图实际检查时最容易被问的是“失败分支在哪”所以选课序列要补一个容量已满的返回箭头登录序列要补一个密码错误的返回箭头。2.4 状态图选谁开课计划或选课记录的状态迁移至少一个重要对象的状态图我一般选开课计划。状态可以定义为待选、可选、满员、结课。待选是开课计划刚建立、还没开放选课可选是开放选课且选课人数小于人数限制满员是选课人数等于人数限制结课是成绩录入完成。事件分别是开放选课、选课成功、退课成功、录入成绩。状态图不用画成 UML 教科书但每个状态要有进入条件比如“满员”状态的进入条件是Selected Capacity退出条件是退课成功。选课记录也可以画状态图已选、已退、已出成绩。已选到已退是退课事件已选到已出成绩是录入成绩事件已退不能直接到已出成绩。这个状态图更贴近代码里的业务约束报告里放一个就够。状态图的价值在于逼你想清楚哪些操作允许、哪些操作要拦截比如已退的选课记录不能再次退课已出成绩的记录不能随便删除。3. 连接 Access 2000ODBC 数据源、BDE 入口与 ADOConnection 的参数表旧工具链里最容易让人怀疑人生的是连接数据库。指导书附录给了 13 步建数据源又在 C Builder 里用 ADOConnection 连 ODBC 数据源。很多同学照着做BDE Administrator 里 Open 之后字体变黑以为成功了回到程序里还是报“未发现数据源名称”。这里要把三个东西分开看Access 文件是数据ODBC 数据源是名字ADOConnection 是程序里的连接对象。BDE Administrator 只是旧版入口真正生效的是 ODBC 数据源管理器里那条 DSN。3.1 为什么旧项目绕不开 ODBCDSN 是应用和 Access 之间的合同C Builder 6.0 里的 ADO 组件通过 OLE DB 访问数据Access 2000 的提供程序常见走MSDASQL也就是 OLE DB 到 ODBC 的桥。DSN 里保存了驱动名、数据库路径、登录方式程序只认数据源名。这样做的好处是换数据库路径时只改 DSN不用改代码坏处是 DSN 建错、位数不对、名字多一个空格程序就找不到。课程设计是单机模式用用户 DSN 就够换 Windows 账户后如果还要用建系统 DSN 更稳。ODBC 数据源管理器有 32 位和 64 位两个入口。C Builder 6.0 编出来的是 32 位程序必须用 32 位管理器建 DSN。常见现象是“我明明建了数据源测试连接也成功程序就是找不到”原因往往是打开的是 64 位管理器。可以在开始菜单搜索“ODBC”看有没有“32 位”字样或者直接运行%WINDIR%\SysWOW64\odbcad32.exe。这个细节不写进报告也行但排错时必须先查。提示数据源名建议用英文加下划线比如CourseDSN不要用带全角空格的中文名。中文名不是不能用而是排错时肉眼很难看出全角空格和半角空格的区别。3.2 建 DSN 的 13 步要留下证据数据源名、路径、驱动三件套指导书附录的步骤可以照做但要在报告里留下三样证据数据源名、Access 文件绝对路径、驱动名称。步骤大致是打开 ODBC 数据源管理器添加Microsoft Access Driver (*.mdb)数据源名填CourseDSN数据库选择C:\CourseDesign\选课.mdb确定后回到管理器能看到这条 DSN。如果系统里没有(*.mdb)驱动说明只装了新版 Access 驱动可以选(*.mdb, *.accdb)但报告里要写实际使用的驱动名不要照抄指导书。BDE Administrator 那一段可以保留作为过程记录但不要把它当成唯一路径。指导书里 Object→New→Microsoft Access Driver→odbc1→ODBC Administrator→添加数据源→Apply→选 ODBC DSN→Open这一串操作的本质还是在 ODBC 管理器里建 DSN。BDE 里 Open 成功只证明 BDE 别名能打开不证明 ADOConnection 能连。实际做课程设计时我一般直接建 ODBC DSN然后到 C Builder 里用 ADOConnection 的 Build 按钮选数据源少绕一层。参数建议值说明数据源名CourseDSN程序连接串里必须完全一致驱动Microsoft Access Driver (*.mdb)没有就选带 accdb 的版本数据库路径C:\CourseDesign\选课.mdb路径不要带全角字符登录名空Access 文件没有数据库用户时留空密码空如果加了数据库密码才填只读不勾选课和退课要写入DSN 类型用户 DSN 或系统 DSN单机当前用户用用户 DSN 即可Access 文件所在目录必须可写。把.mdb放在只读目录、光盘目录或者没有写权限的共享目录查询能通选课插入会失败。这个坑在机房环境很常见现象是“查询开课正常一选课就报错”原因不是 SQL 写错而是文件权限不对。把文件复制到本地工作目录去掉只读属性再测试一次写入。3.3 BDE Administrator 只是旧入口ADOConnection 真正吃的是 ODBC DSN在 C Builder 6.0 里新建 Application保存项目后从 ADO 页拖一个TADOConnection到窗体上。双击它点Build选择“使用数据源名称”下拉框里选CourseDSN点“测试连接”。测试通过后确定把LoginPrompt设为FalseConnected设为True。LoginPromptFalse的作用是避免程序启动时弹登录框单机 Access 没有数据库用户弹框只会让演示中断。ConnectedTrue表示窗体创建时就连接调试阶段方便发布时可以在登录成功后再打开连接。连接串常见形式是ProviderMSDASQL.1;Persist Security InfoFalse;Data SourceCourseDSN。Data Source后面就是 DSN 名不是 Access 文件路径。有些同学把路径直接写在这里测试连接也能过但换一台机器就失效。用 DSN 的好处是路径变了只改 DSN。Persist Security InfoFalse表示连接打开后不保留密码信息单机无密码时影响不大保留默认即可。ADOConnection 属性建议值作用ConnectionStringProviderMSDASQL.1;Data SourceCourseDSN指定 ODBC 数据源LoginPromptFalse不弹数据库登录框Connected调试时 True发布时按需控制连接时机KeepConnectionTrue保持连接减少反复打开IsolationLevel默认单机 Access 不需要改连接成功后拖TADOQuery把Connection指向ADOConnection再拖TDataSource把DataSet指向ADOQuery最后拖TDBGrid把DataSource指向TDataSource。这条链路是 C Builder 里最常用的数据感知组合。查询开课情况时ADOQuery.SQL.Text写 SELECTOpen后表格自动显示。写操作时用ExecSQL不要用Open否则会报“查询没有返回结果集”。3.4 连接串与登录参数LoginPrompt、Connected、测试连接测试连接要注意顺序先确认 ODBC 管理器里 DSN 存在再确认 C Builder 是 32 位程序最后确认 Access 文件没有被其他程序独占打开。Access 2000 的.mdb被 Access 界面打开时ODBC 仍然能读但写入可能受锁影响。演示前把 Access 关掉避免“选课偶发失败”的玄学问题。如果测试连接报“未发现数据源名称并且未指定默认驱动程序”先查 DSN 名是否完全一致再查 32/64 位不要急着重装 C Builder。登录功能的连接时机可以这样安排主窗体创建时ConnectedFalse登录按钮里先ADOConnection-ConnectedTrue执行登录查询成功后再打开主界面。这样做的好处是数据库文件路径不对时程序启动不会直接崩而是弹一个可读的错误提示。错误提示不要只写Connection failed要带上 DSN 名和原始错误信息排错时能省很多时间。注意如果程序在机房能跑、回到宿舍不能跑优先检查 DSN 是不是建在当前用户下以及 Access 文件路径是不是还指向机房目录。用户 DSN 不跟着项目文件走换机器要重建。4. C Builder 6.0 落地登录、选课、退课与成绩查询的事件链界面不需要做得像商业软件但事件链要清楚。登录界面负责验证学号和密码主界面负责导航开课查询界面用表格显示课程、教师、教室、人数限制、已选人数选课界面负责提交选课和退课成绩界面负责按学号查成绩。每个界面不要直接拼 SQL 字符串参数化查询能挡住大部分引号和特殊字符问题。课程设计的数据量小但“OBrien”这种姓名或课程名里的单引号足够让拼接 SQL 翻车。4.1 窗体骨架一个连接、三个查询、四个界面我一般放一个TADOConnection在主窗体上其他窗体通过主窗体访问避免每个窗体各建一个连接。查询组件按用途分登录查询、开课查询、选课查询、成绩查询。数据源和表格按界面配。登录界面用两个TEdit和一个TButton密码框设PasswordChar*。主界面用按钮或菜单跳转。开课查询界面用TDBGrid显示结果再加课程名、教师名两个查询条件框。选课界面显示当前选中的开课号和课程名提供“选课”和“退课”按钮。成绩界面用TDBGrid显示课名、学分、平时成绩、考试成绩、总评成绩。界面主要控件绑定的查询登录Edit、Button按学号和密码查学生开课查询DBGrid、Edit、Button按课程名或教师名查开课选课/退课DBGrid、Button、Label查已选课程、插入或删除选课记录成绩查询DBGrid、Edit、Button按学号查成绩和总评控件命名要能看懂edtSno、edtPwd、btnLogin、qryLogin比Edit1、Button1好排错。报告里贴界面图时控件名不用出现但代码里能对应上。主窗体关闭时把ADOConnection-Connected设为False避免 Access 文件被占用。4.2 登录与查询参数化 SQL 避免拼接登录查询的 SQL 可以写成SELECT Sno, Sname FROM Student WHERE Sno:Sno AND Pwd:Pwd。参数用ParamByName赋值不要用Format拼字符串。下面是 C Builder 事件里的写法关键在Parameters-ParamByName和Eof判断。// 登录按钮事件参数化查询避免拼接 SQL qryLogin-Close(); qryLogin-SQL-Clear(); qryLogin-SQL-Add(SELECT Sno, Sname FROM Student WHERE Sno:Sno AND Pwd:Pwd); qryLogin-Parameters-ParamByName(Sno)-Value Trim(edtSno-Text); qryLogin-Parameters-ParamByName(Pwd)-Value Trim(edtPwd-Text); qryLogin-Open(); if (!qryLogin-Eof) { CurrentSno qryLogin-FieldByName(Sno)-AsString; // 打开主界面记录当前登录学生 } else { ShowMessage(学号或密码不正确); }这段代码的逻辑是先关查询、清 SQL、加 SQL、赋参数、打开结果集。Trim去掉首尾空格避免用户复制学号时带空格。Eof为假表示查到记录登录成功为真表示没有匹配。密码字段在课程设计里可以存明文但报告里要写“生产环境应存哈希值”不要把明文密码当成正确设计。查询开课情况的 SQL 用连接查询把课程名、教师名、教室、人数限制、已选人数一起查出来SELECT o.OfferingID, c.Cname, t.Tname, o.Classroom, o.Capacity, o.Selected FROM Offering o INNER JOIN Course c ON o.Cno c.Cno INNER JOIN Teacher t ON o.Tno t.Tno WHERE c.Cname LIKE % :Cname % ORDER BY c.CnameLIKE里的参数写法在 Access ODBC 下可以用%通配符。如果参数为空可以在代码里判断后换成LIKE *或去掉条件。开课查询的结果集绑定到TDBGrid用户选中一行后把OfferingID存到变量里供选课按钮使用。不要用表格的行号当开课号排序一变就行号错位。4.3 选课与退课事务里做条件更新选课是整套系统里最值得写进报告的部分。正确顺序是开事务、检查重复、插入选课记录、条件更新选课人数、判断更新是否成功、提交或回滚。不要在插入前只做一次SELECT COUNT(*)判断容量因为检查和插入之间可能被别人插队单机场景虽然并发少但演示时开两个程序就能复现超选。更稳的做法是把容量条件写进 UPDATEWHERE OfferingID:Oid AND Selected Capacity更新影响行数为 0 就回滚。// 选课事务 条件更新防止超选 conn-BeginTrans(); try { // 先插入选课记录唯一索引兜底重复选课 qryEnroll-Close(); qryEnroll-SQL-Clear(); qryEnroll-SQL-Add(INSERT INTO Enrollment(Sno, OfferingID) VALUES(:Sno, :Oid)); qryEnroll-Parameters-ParamByName(Sno)-Value CurrentSno; qryEnroll-Parameters-ParamByName(Oid)-Value CurrentOfferingId; qryEnroll-ExecSQL(); // 只有未满员才把已选人数加一 qryEnroll-SQL-Clear(); qryEnroll-SQL-Add(UPDATE Offering SET SelectedSelected1 WHERE OfferingID:Oid AND Selected Capacity); qryEnroll-Parameters-ParamByName(Oid)-Value CurrentOfferingId; qryEnroll-ExecSQL(); if (qryEnroll-RowsAffected 1) { conn-CommitTrans(); } else { conn-RollbackTrans(); ShowMessage(人数已满选课失败); } } catch (...) { conn-RollbackTrans(); ShowMessage(选课失败可能重复选课或数据被占用); }BeginTrans、CommitTrans、RollbackTrans是 ADOConnection 的事务方法。插入和更新在同一个事务里任何一步失败都回滚。RowsAffected表示上一条语句影响的行数等于 1 说明容量条件满足等于 0 说明已经满员。部分 Access ODBC 驱动下RowsAffected可能返回 -1这时可以在更新后再查一次Selected和Capacity对比或者用SELECT COUNT(*)验证。报告里要写清楚你用的判断方式不要只写“如果满了就提示”。选课记录表上必须有(Sno, OfferingID)唯一索引重复选课时 INSERT 会抛异常进入catch回滚。退课的顺序反过来先删选课记录删除影响行数为 1 再把已选人数减一条件加Selected 0防止人数减成负数。// 退课先删记录再减人数删除失败就不减 conn-BeginTrans(); try { qryEnroll-SQL-Clear(); qryEnroll-SQL-Add(DELETE FROM Enrollment WHERE Sno:Sno AND OfferingID:Oid); qryEnroll-Parameters-ParamByName(Sno)-Value CurrentSno; qryEnroll-Parameters-ParamByName(Oid)-Value CurrentOfferingId; qryEnroll-ExecSQL(); if (qryEnroll-RowsAffected 1) { qryEnroll-SQL-Clear(); qryEnroll-SQL-Add(UPDATE Offering SET SelectedSelected-1 WHERE OfferingID:Oid AND Selected 0); qryEnroll-Parameters-ParamByName(Oid)-Value CurrentOfferingId; qryEnroll-ExecSQL(); conn-CommitTrans(); } else { conn-RollbackTrans(); ShowMessage(没有找到对应选课记录); } } catch (...) { conn-RollbackTrans(); ShowMessage(退课失败); }退课的业务规则要补一条已经录入成绩的选课记录不允许退课。可以在 DELETE 前查成绩字段是否为空或者在 SQL 里加AND FinalScore IS NULL。课程设计不要求做权限系统但报告里写清这条规则状态图里的“已出成绩不能退课”就有依据。4.4 成绩与总评权重参数写进配置而不是硬编码成绩查询按学号查SQL 连接选课表、开课表、课程表显示课名、学分、平时成绩、考试成绩、总评成绩。总评成绩的计算权重常见做法是平时 30%、考试 70%但指导书没有写死报告里要写明采用的权重。不要把0.3和0.7散落在三个地方定义一个常量或配置项录入成绩和查询成绩共用。SELECT c.Cname, c.Credit, e.UsualScore, e.ExamScore, e.FinalScore FROM Enrollment e INNER JOIN Offering o ON e.OfferingID o.OfferingID INNER JOIN Course c ON o.Cno c.Cno WHERE e.Sno :Sno ORDER BY c.Cname录入成绩时先更新平时成绩和考试成绩再计算总评写回。总评可以写成UsualScore * 0.3 ExamScore * 0.7保留一位小数。如果平时成绩或考试成绩为空总评也置空不要按 0 计算。查询成绩界面里空值显示为“未录入”比显示 0 更符合教学场景。成绩录入权限只给教师角色学生界面只读报告里的用例图要把这条权限边界画出来。5. 避坑与排查旧工具链里最容易翻车的 5 个现场旧工具链的问题有很强的现场性代码没错、配置没错结果就是连不上或者写不进。下面 5 条是课程设计里出现频率很高的现场按“现象→原因→解决”记录答辩前照着排一遍比重新装环境省时间。5.1 数据源连不上先查位数和名称不要重装 C Builder现象ODBC 管理器里测试连接成功C Builder 的 ADOConnection 点测试连接报“未发现数据源名称并且未指定默认驱动程序”。原因通常有两个一是 C Builder 6.0 是 32 位程序DSN 却建在 64 位 ODBC 管理器里二是 DSN 名带全角空格或大小写不一致连接串里的Data Source和实际名称不完全匹配。解决打开 32 位 ODBC 管理器重建同名 DSN复制数据源名到连接串不要手打在 ADOConnection 的 Build 对话框里直接下拉选择 DSN让 IDE 生成连接串。另一个现象是 BDE Administrator 里 Open 字体变黑程序仍然连不上。原因是 BDE 别名和 ADOConnection 用的 ODBC DSN 是两套东西BDE 能打开不代表 ADO 能打开。解决把 BDE 那一步当作过程记录真正连接以 ADOConnection 的测试连接为准LoginPrompt设为False避免弹框被取消后连接处于半开状态。这类问题看着玄学查位数和名称基本能定位。5.2 选课超限与重复记录唯一索引和事务缺一不可现象人数限制 30选课人数显示 31或者同一学生同一门课出现两条选课记录。原因先SELECT COUNT(*)判断人数再 INSERT检查和写入之间没有锁选课表没有唯一索引重复提交按钮就插两条。解决给选课表建(Sno, OfferingID)唯一索引选课放进事务用UPDATE Offering SET SelectedSelected1 WHERE OfferingID:Oid AND SelectedCapacity做条件更新更新影响行数不为 1 就回滚。按钮点击后先禁用等事务结束再恢复防止用户连点。还有一个现象是退课以后人数不减或者减成负数。原因是删除选课记录和更新人数不在一个事务里或者更新条件没加Selected0。解决删除影响行数为 1 才执行减一减一条件加Selected0两步放在同一事务。选课人数是冗余字段所有写入路径都必须维护它报告里要写清哪些操作会改这个字段。5.3 中文、日期、空值三类字段最容易把数据写坏现象学生姓名显示成问号出生年月变成 1900-01-01成绩为空时总评变成 0。原因Access 字段文本长度不够姓名被截断日期用字符串拼接区域格式和数据库格式不一致空值参与算术运算被当成 0。解决姓名字段至少 20 位地址 50 位日期用参数化查询参数类型设为日期不要拼yyyy/mm/dd字符串总评计算前判断平时成绩和考试成绩是否为空为空就保持空值。中文乱码还可能来自连接串或控件字体但课程设计里更常见的是字段长度和字符集。Access 2000 的文本字段默认长度 50姓名一般够用课程名和教室名要检查。导入数据时先用少量中文测试确认写入后查询、表格显示、报告截图都正常。日期字段在 Access 里显示格式可以设成yyyy-mm-dd但底层存储是日期值参数化写入最稳。5.4 报告与代码两张皮测试序列要带前置状态现象报告用例图里有“管理员审核选课”代码里根本没有这个功能序列图画了五个生命线程序里只有一个窗体。原因先写报告后改代码或者照着模板抄图没有按实际实现回填。解决以数据库表和代码为准回填图删掉没实现的用例补上实际存在的失败分支报告里的每个图下面写一句“对应代码位置/表名”答辩时能指出来。测试部分不要只写输入输出要写前置状态、输入对象、执行动作、预期状态、清理动作。现象测试数据只有“输入正确密码登录成功”和“输入错误密码登录失败”两条。原因是把测试当成功能演示。解决按对象状态迁移设计 20 条不同对象测试序列登录、查询、选课、退课、成绩各覆盖成功和失败分支选课要覆盖重复选课、容量边界、退课后重选。测试序列编号和报告里的截图对应评审时本文还有配套的精品资源点击获取