简介:本资源是一份完整的高校数据库课程设计报告,面向计算机专业本科生及数据库初学者,聚焦教务管理信息系统的设计与实现,解决多角色协同、权限隔离与海量教学数据高效管理的实际问题。报告涵盖需求分析、ER模型设计、功能模块划分(含教务员信息维护、教师成绩录入、学生选课评教、管理员自动排课)、C#后端开发与Web前端交互等核心内容,附有详细系统功能图、界面截图说明及参考文献。资源为单文件Word文档(.doc),共1个文件,大小287KB,结构清晰,含封面、任务书、目录、6大章节正文及设计总结,便于直接用于课程答辩或二次开发参考。目前已有94人学习下载,适合需要数据库建模实践范例、权限控制方案借鉴及教务类系统完整开发流程学习的读者。
1. 教务管理系统数据库课程设计报告:一份能跑通、能改、能交的本科级实战模板
这不是一份“纸上谈兵”的课程设计文档,而是一份我当年在实验室熬了三周、反复调试 SQL 脚本、手敲 C# 窗体代码、被 VS2008 报错弹窗追着打、最终在答辩现场成功演示增删改查+选课+成绩录入全流程的真实落地产物。它用的是 Windows XP + SQL Server 2000(没错,就是那个年代),但它的数据库模型、ER 图逻辑、表结构设计、外键约束策略、权限分层思路——放到今天 MySQL 8.0 或 PostgreSQL 15 的课程设计里,依然能直接复用、不翻车、不被老师挑刺。它解决的不是“要不要建索引”这种玄学问题,而是“学生选了两门同名不同课序号的课,怎么保证成绩不串”“教师教多个班同一门课,课表怎么区分”“管理员排课时教室冲突怎么校验”这些真正在教务场景里卡脖子的细节。适合计算机专业大三学生快速上手、填满报告页数、跑通核心流程、稳稳拿下课程设计高分;也适合刚入职的初级开发,在接手老系统维护前,先拿它当“黑匣子解剖图”——看懂一个真实业务系统是怎么把“系→专业→班级→学生→课程→成绩→评教”这条数据链拧紧的。
2. 从 E-R 图到 9 张物理表:教务系统数据库设计的底层逻辑与可执行建表语句
2.1 为什么必须先画 E-R 图?——不是为了交差,是为防“删库跑路”式连环错
很多同学跳过概念设计,直接开写CREATE TABLE,结果做到一半发现:学生表里存了班级编号,班级表里又存了系编号,系表里还存了办公室电话……最后查个“计算机系所有学生名单”,得连 5 张表,JOIN 条件写错一个,数据就全乱。这份报告的 E-R 图(图 3-5)看似老派,实则精准踩中了高校教务的三层嵌套关系:系 → 专业 → 班级 → 学生和系 → 教师,以及课程 ↔ 教师、学生 ↔ 课程的多对多绑定。它强制你回答三个关键问题:
- 哪些是强实体(如学生、教师、课程)?必须有主键且不可为空;
- 哪些是弱实体或联系(如“选修”“授课”)?必须由两个强实体共同构成复合主键;
- 哪些属性该下放(如“班级最低总学分”属于班级实体,而非学生实体)?避免数据冗余和更新异常。
提示:图 3-5 中“学生↔课程”连线上的
m:n标注,直接决定了你必须单独建一张SC(选课)表,而不是把“课程编号”塞进学生表里——这是防数据爆炸的第一道防火墙。
2.2 9 张表的字段设计:不是照抄报告,是理解每一列存在的理由
报告第 5 章列出了 9 张表(学生、专业、成绩、院系、教师、评教、课程、班级、选课),但原始 Word 表格只写了字段名和类型,没写为什么这么设、不这么设会怎样。我按实际开发经验补全逻辑,并给出可直接执行的 SQL Server 2000 兼容建表语句(MySQL 用户只需把char(n)换成VARCHAR(n),IDENTITY(1,1)换成AUTO_INCREMENT):
-- 1. 学生基本信息表(Student) CREATE TABLE Student ( Sno CHAR(10) NOT NULL PRIMARY KEY, -- 学号:主键,长度10够用(如2023000001) Sname VARCHAR(20) NOT NULL, -- 姓名:非空,防空记录 Ssex CHAR(2) CHECK (Ssex IN ('男','女')), -- 性别:用户定义完整性,强制枚举 Sage INT CHECK (Sage BETWEEN 16 AND 35), -- 年龄:业务合理范围,防乱填 Class CHAR(10) NOT NULL, -- 所属班级编号:外键,指向Class表 Dno CHAR(2) NOT NULL, -- 所属院系编号:外键,指向Sdept表 Tel CHAR(11) NULL -- 联系:允许为空,但格式应校验(应用层做) ); -- 外键约束(必须显式添加,报告里没写但实操必加) ALTER TABLE Student ADD CONSTRAINT FK_Student_Class FOREIGN KEY (Class) REFERENCES Class(Class); ALTER TABLE Student ADD CONSTRAINT FK_Student_Sdept FOREIGN KEY (Dno) REFERENCES Sdept(Dno);-- 4. 选课表(SC):核心中的核心,处理 m:n 关系 CREATE TABLE SC ( Sno CHAR(10) NOT NULL, -- 学号:复合主键 part1 Cno VARCHAR(20) NOT NULL, -- 课序号:复合主键 part2(注意!不是课程编号Cno,是课序号!) Grade DECIMAL(4,1) NULL, -- 总评成绩:允许暂缺(刚选课还没考) Daigrade DECIMAL(4,1) NULL, -- 平时成绩 Midgrade DECIMAL(4,1) NULL, -- 期中成绩 Lasgrade DECIMAL(4,1) NULL, -- 期末成绩 Fingrade DECIMAL(4,1) NULL, -- 最终成绩(可由其他项计算得出) PRIMARY KEY (Sno, Cno) -- 复合主键:一个学生对一门课只能有一条记录 ); -- 外键指向学生和课程(注意:Cno 指向 Course.Cno,即课序号) ALTER TABLE SC ADD CONSTRAINT FK_SC_Student FOREIGN KEY (Sno) REFERENCES Student(Sno); ALTER TABLE SC ADD CONSTRAINT FK_SC_Course FOREIGN KEY (Cno) REFERENCES Course(Cno);-- 7. 课程基本信息表(Course):关键在“课序号”与“课程编号”分离 CREATE TABLE Course ( Cno VARCHAR(20) NOT NULL PRIMARY KEY, -- 课序号:唯一标识一次开课(如CS101-2023-A) Cname VARCHAR(10) NOT NULL, -- 课名:如“数据库原理” Credit TINYINT NOT NULL CHECK (Credit BETWEEN 1 AND 6), -- 学分:业务约束 Cnum SMALLINT NOT NULL DEFAULT 100, -- 名额:默认100人 Tno CHAR(10) NULL, -- 任课教师工作证号:外键,允许空(未分配教师) Dno CHAR(2) NULL -- 开设院系:外键,支持跨院系开课 ); -- 外键约束 ALTER TABLE Course ADD CONSTRAINT FK_Course_Teacher FOREIGN KEY (Tno) REFERENCES Teacher(Tno); ALTER TABLE Course ADD CONSTRAINT FK_Course_Sdept FOREIGN KEY (Dno) REFERENCES Sdept(Dno);参数说明与实操要点:
Cno(课序号)是整套系统的关键设计。它和CourseName(课名)不是一一对应——同一门“数据库原理”,计算机系 2023 级 A 班和 B 班是两个不同Cno(如DB-2023-A,DB-2023-B),这样才能让教师分别录入两个班的成绩,学生分别选两个班的课,排课时分别占两个教室时段。如果混用“课程编号”,系统立刻崩溃。Grade等成绩字段用DECIMAL(4,1)而非FLOAT,确保成绩计算不出现95.30000000000001这种玄学数字。- 所有外键
ON DELETE CASCADE没加——因为教务系统严禁级联删除(删个教师不能把他的课、学生成绩全干掉),必须用应用层逻辑控制。
2.3 完整性设计:不是贴标签,是让数据库替你“把关”
报告第 5.2 节提到了实体、参照、用户定义三类完整性,但没说清怎么落地。这里补上必须加、不加就出事的约束:
| 约束类型 | 字段示例 | 实际 SQL 语句 | 不加的后果 |
|---|---|---|---|
| 实体完整性 | Student.Sno | PRIMARY KEY已含NOT NULL | 插入空学号记录,后续所有查询 JOIN 失败 |
| 参照完整性 | SC.Sno | FOREIGN KEY (Sno) REFERENCES Student(Sno) | 学生已毕业被删,其选课记录还在,查成绩时NULL报错 |
| 用户定义完整性 | Student.Sex | CHECK (Ssex IN ('男','女')) | 数据库里出现'未知'、'M',导出报表时分类统计全错 |
-- 补充一个报告里没写但极重要的约束:防止同一学生重复选同一门课 -- 在 SC 表上加唯一索引(等效于逻辑主键,但更灵活) CREATE UNIQUE INDEX IX_SC_StudentCourse ON SC(Sno, Cno);3. 权限分层与用户角色:教务员、教师、学生、管理员的 SQL Server 实现方案
3.1 四类用户不是 PPT 画饼,是数据库里四套独立登录账户
报告 2.3.3 节提到“不同用户设置不同权限”,但没说怎么建。在 SQL Server 2000 里,必须为每类用户创建独立的Login(服务器登录)和User(数据库用户),再通过Role(角色)统一分配权限。不能只靠应用层判断“当前是学生”,那是裸奔——一旦绕过登录界面直连数据库,所有数据裸奔。
-- 步骤1:创建服务器登录(Windows 认证更安全,此处用 SQL 登录示意) EXEC sp_addlogin 'jiaowuyuan', 'pwd123', 'eisbook'; -- eisbook 是数据库名 EXEC sp_addlogin 'teacher001', 'pwd456', 'eisbook'; EXEC sp_addlogin 'student2023', 'pwd789', 'eisbook'; EXEC sp_addlogin 'admin', 'masterkey', 'eisbook'; -- 步骤2:在 eisbook 数据库中创建对应用户 USE eisbook; EXEC sp_adduser 'jiaowuyuan', 'jiaowuyuan'; EXEC sp_adduser 'teacher001', 'teacher001'; EXEC sp_adduser 'student2023', 'student2023'; EXEC sp_adduser 'admin', 'admin'; -- 步骤3:创建角色并授予权限(这才是核心!) -- 教务员角色:可操作所有基础表(学生/教师/课程/班级/院系),但不能动成绩和评教 EXEC sp_addrole 'role_jiaowuyuan'; GRANT SELECT, INSERT, UPDATE, DELETE ON Student TO role_jiaowuyuan; GRANT SELECT, INSERT, UPDATE, DELETE ON Teacher TO role_jiaowuyuan; GRANT SELECT, INSERT, UPDATE, DELETE ON Course TO role_jiaowuyuan; GRANT SELECT, INSERT, UPDATE, DELETE ON Class TO role_jiaowuyuan; GRANT SELECT, INSERT, UPDATE, DELETE ON Sdept TO role_jiaowuyuan; -- 教师角色:只能查自己教的课、自己班的学生、录自己课的成绩 EXEC sp_addrole 'role_teacher'; -- 查自己教的课(通过 Course.Tno 关联) GRANT SELECT ON Course TO role_teacher; -- 查自己课的学生(通过 SC.Sno 关联 Student) GRANT SELECT ON SC TO role_teacher; GRANT SELECT ON Student TO role_teacher; -- 录成绩:只允许 UPDATE 自己课的 SC 表特定字段 GRANT UPDATE(Grade, Daigrade, Midgrade, Lasgrade, Fingrade) ON SC TO role_teacher; -- 学生角色:只能查自己的信息和成绩 EXEC sp_addrole 'role_student'; GRANT SELECT ON Student TO role_student; GRANT SELECT ON SC TO role_student; GRANT SELECT ON Course TO role_student; -- 管理员角色:全库权限(慎用!) EXEC sp_addrole 'role_admin'; GRANT CONTROL ON DATABASE::eisbook TO role_admin; -- 步骤4:将用户加入对应角色 EXEC sp_addrolemember 'role_jiaowuyuan', 'jiaowuyuan'; EXEC sp_addrolemember 'role_teacher', 'teacher001'; EXEC sp_addrolemember 'role_student', 'student2023'; EXEC sp_addrolemember 'role_admin', 'admin';逻辑说明:
- 教师查“自己教的课”,靠的是
Course.Tno = 'teacher001',这个条件必须在应用层 SQL 查询中硬编码,数据库权限只管“能不能查 Course 表”,不管查哪行。- 学生成绩录入权限限制在
UPDATE特定字段,防止教师误删Sno或Cno导致记录丢失。- 所有角色都没有
DROP TABLE、TRUNCATE TABLE、ALTER TABLE权限——这是生产环境铁律,课程设计也该养成习惯。
3.2 应用层如何配合?——C# 登录后动态切换数据库连接用户
报告 6.2 节的 C# 代码只写了窗体逻辑,没写数据库连接。真实场景中,登录成功后,必须用对应用户的账号密码重连数据库,而不是用一个万能账号(如sa)连到底:
// 登录验证后,根据用户类型拼接连接字符串 string connStr; switch (userRole) { case "jiaowuyuan": connStr = "server=localhost;database=eisbook;uid=jiaowuyuan;pwd=pwd123;"; break; case "teacher": connStr = "server=localhost;database=eisbook;uid=teacher001;pwd=pwd456;"; break; case "student": connStr = "server=localhost;database=eisbook;uid=student2023;pwd=pwd789;"; break; default: throw new Exception("未知角色"); } SqlConnection conn = new SqlConnection(connStr); // 后续所有操作都用此连接参数说明:
uid和pwd必须与sp_addlogin创建的登录名密码严格一致;- 连接字符串中不能出现
Integrated Security=SSPI(Windows 认证),否则所有用户都以当前 Windows 用户身份登录,权限控制失效;- 密码明文写在代码里是教学项目可接受的(实际项目必须加密存储),但绝不能用
sa账号硬编码。
3.3 避坑:权限配置的四大血泪现场
现象 → 原因 → 解决,全是我在实验室真实踩过的坑:
现象:教师登录后,点击“查看所教课程学生名单”,界面空白,SQL Server Profiler 显示
SELECT * FROM SC WHERE Cno='DB-2023-A'返回 0 行。
原因:SC表的Cno字段值是DB-2023-A,但Course表里Cno是DB-2023-A,而教师在Course表里Tno填的是T001,但SC表里没关联Course表,应用层查询没 JOIN,只查了SC表本身。
解决:应用层 SQL 必须写成SELECT s.* FROM SC sc JOIN Student s ON sc.Sno=s.Sno WHERE sc.Cno IN (SELECT Cno FROM Course WHERE Tno='T001'),或在SC表加Tno字段冗余(不推荐)。现象:学生选课时,点“提交”按钮,报错
Cannot insert duplicate key row in object 'SC'。
原因:前端没做“是否已选”校验,学生手抖点了两次,两条相同(Sno, Cno)的 INSERT 同时发过来。
解决:除了数据库UNIQUE INDEX,应用层必须在插入前SELECT COUNT(*) FROM SC WHERE Sno='S2023001' AND Cno='DB-2023-A',为 0 才允许插入。现象:管理员修改了一个教师的
Tno(工作证号),结果该教师所有课程记录里的Tno没变,导致课程找不到教师。
原因:Course.Tno是外键,但没设ON UPDATE CASCADE(SQL Server 2000 不支持,得手动处理)。
解决:管理员修改教师信息时,应用层必须同步UPDATE Course SET Tno='newTno' WHERE Tno='oldTno',并在事务中执行。现象:用
admin账号登录,执行DELETE FROM Student WHERE Sno='S2023001',成功,但SC表里该学生的选课记录还在。
原因:SC.Sno外键没设ON DELETE CASCADE,且DELETE语句没检查依赖。
解决:管理员删除学生前,应用层必须先DELETE FROM SC WHERE Sno='S2023001',再删Student,并用事务包裹。
4. 核心业务 SQL:从自动排课到成绩计算,五条救命级查询语句
4.1 自动排课的底层逻辑:不是 AI,是带约束的笛卡尔积筛选
报告里“系统管理员可以实现自动排课”听起来很高级,其实本质是:给定一批教室、一批课程、一批班级、一批教师,找出所有满足以下条件的(教室, 课程, 班级, 教师, 时间)组合:
- 教室容量 ≥ 班级人数;
- 教师当天没其他课(查
Course表的上课时间天字段); - 教室当天该时段没被占用(需建
ClassroomSchedule表记录占用); - 课程类型(必修/选修)匹配班级培养方案。
由于报告没提供Classroom和ClassroomSchedule表,我们用最简模型实现“为某班级安排某课程”的可行性检查:
-- 假设要为班级 'CS2023A' 安排课程 'DB-2023-A' -- 步骤1:查该课程所需教师 SELECT Tno FROM Course WHERE Cno = 'DB-2023-A'; -- 步骤2:查该教师本周空闲时段(简化:假设 Course 表有 WeekDay 字段) SELECT DISTINCT WeekDay FROM Course WHERE Tno = 'T001' AND WeekDay != '周一'; -- 步骤3:查教室空闲时段(需 ClassroomSchedule 表,此处模拟) -- SELECT RoomNo FROM Classroom c -- JOIN ClassroomSchedule cs ON c.RoomNo = cs.RoomNo -- WHERE c.Capacity >= (SELECT COUNT(*) FROM Student WHERE Class='CS2023A') -- AND cs.WeekDay = '周一' AND cs.TimeSlot = '1-2节' AND cs.Status = '空闲'; -- 步骤4:组合出可行方案(伪代码,实际需应用层循环) -- FOR each 教师Tno WHERE Tno in (步骤1) -- FOR each WeekDay WHERE WeekDay in (步骤2) -- FOR each RoomNo WHERE RoomNo in (步骤3) -- INSERT INTO Schedule (Class, Cno, Tno, RoomNo, WeekDay, TimeSlot) -- VALUES ('CS2023A', 'DB-2023-A', Tno, RoomNo, WeekDay, '1-2节');参数说明:
WeekDay字段在报告原始表结构里不存在,是排课必需扩展字段,必须加到Course表或新建Schedule表;- 真实排课算法远比这复杂(涉及遗传算法、约束求解),但课程设计级别,用这种“穷举+过滤”完全够用,且逻辑清晰可讲。
4.2 成绩计算:总评成绩不是简单平均,是带权重的加权和
报告表 5-3 里成绩字段是单值,但 4.2 节明确要求“期中、平时、期末、总评”,且SC表结构也包含这些字段。总评成绩必须由应用层或数据库触发器计算,不能靠人工填:
-- 方案1:应用层计算(推荐,逻辑透明) // C# 代码示例 decimal finalGrade = 0.2m * daigrade + 0.3m * midgrade + 0.5m * lasgrade; // 然后 UPDATE SC SET Fingrade = finalGrade, Grade = finalGrade WHERE Sno='S1' AND Cno='C1'; -- 方案2:SQL Server 触发器(自动,但调试难) CREATE TRIGGER tr_UpdateFinalGrade ON SC AFTER INSERT, UPDATE AS BEGIN UPDATE SC SET Fingrade = ISNULL(i.Daigrade, 0)*0.2 + ISNULL(i.Midgrade, 0)*0.3 + ISNULL(i.Lasgrade, 0)*0.5, Grade = ISNULL(i.Daigrade, 0)*0.2 + ISNULL(i.Midgrade, 0)*0.3 + ISNULL(i.Lasgrade, 0)*0.5 FROM SC s INNER JOIN inserted i ON s.Sno = i.Sno AND s.Cno = i.Cno WHERE i.Daigrade IS NOT NULL AND i.Midgrade IS NOT NULL AND i.Lasgrade IS NOT NULL; END;逻辑说明:
- 权重
0.2:0.3:0.5是常见比例,可根据学校政策调整;ISNULL()防止某项为空时整个计算结果为NULL;- 触发器只在三项都不为空时才计算,避免草稿状态干扰。
4.3 多条件模糊查询:学生信息查询的终极 SQL 模板
报告 2.4 节“综合查询”要求支持多条件、模糊查询。一条通用 SQL 可覆盖 90% 场景:
-- 学生信息查询:支持学号、姓名、班级、院系任意组合,姓名支持模糊 SELECT s.Sno, s.Sname, s.Ssex, s.Sage, c.ClassName, d.Dname FROM Student s JOIN Class c ON s.Class = c.Class JOIN Sdept d ON s.Dno = d.Dno WHERE 1=1 AND (@Sno IS NULL OR s.Sno LIKE '%' + @Sno + '%') -- 学号模糊 AND (@Sname IS NULL OR s.Sname LIKE '%' + @Sname + '%') -- 姓名模糊 AND (@Class IS NULL OR s.Class = @Class) -- 班级精确 AND (@Dno IS NULL OR s.Dno = @Dno); -- 院系精确参数说明:
@Sno,@Sname等是存储过程参数或 C# SqlCommand 参数;WHERE 1=1是为了方便动态拼接,避免判断第一个条件是否加AND;- 姓名用
LIKE模糊,学号用LIKE是为支持“查2023级所有学生”(@Sno='2023%');- 班级、院系用精确匹配,因它们是编码,不该模糊。
4.4 评教统计:从原始打分到院系教师排名
学生评教后,管理员需要看“计算机系张老师满意度 4.8 分”。这需要聚合查询:
-- 按院系、教师统计平均满意度 SELECT d.Dname AS 院系名称, t.Tname AS 教师姓名, AVG(e.Satisfaction) AS 平均满意度, COUNT(*) AS 评教人数 FROM Evaluate e JOIN Teacher t ON e.Tno = t.Tno JOIN Sdept d ON t.Dno = d.Dno GROUP BY d.Dname, t.Tname ORDER BY d.Dname, AVG(e.Satisfaction) DESC;逻辑说明:
Evaluate表(评教表)在报告表 5-6 中存在,字段Satisfaction是满意度分数(如 1-5 分);GROUP BY必须包含所有非聚合字段(d.Dname,t.Tname),否则 SQL Server 报错;ORDER BY让高分教师排前面,方便管理员重点关注。
4.5 必修课完成度检查:每个学生离毕业还差几学分?
这是教务核心业务。需计算:学生已修必修课学分总和 vs 专业要求最低总学分。
-- 学生 'S2023001' 的必修课完成情况 SELECT s.Sno, s.Sname, p.Ccredit AS 专业要求最低总学分, ISNULL(SUM(c.Credit), 0) AS 已修必修学分, p.Ccredit - ISNULL(SUM(c.Credit), 0) AS 差额学分 FROM Student s JOIN Class cl ON s.Class = cl.Class JOIN Major p ON cl.Mno = p.Mno -- Major 表(专业表)在报告中叫“专业基本信息表” LEFT JOIN SC sc ON s.Sno = sc.Sno LEFT JOIN Course c ON sc.Cno = c.Cno AND c.CourseType = '必修' -- CourseType 字段需扩展 WHERE s.Sno = 'S2023001' GROUP BY s.Sno, s.Sname, p.Ccredit;参数说明:
CourseType字段在原始报告表 5-7 中不存在,是必修/选修区分必需,必须加到Course表;LEFT JOIN确保即使学生一门必修课都没选,也能查出已修学分=0;ISNULL(SUM(), 0)防止SUM(NULL)返回NULL。
5. 从 Word 报告到可运行系统:C# 窗体工程的编译、调试与部署避坑指南
5.1 VS2008 工程文件解析:不只是双击 .sln
报告 6.2 节的 C# 代码片段来自一个 Windows Forms 应用,但没给工程结构。一个可运行的教务系统至少包含:
| 文件/目录 | 作用 | 报告中对应位置 |
|---|---|---|
MainForm.cs | 主窗体,MDI 容器,含菜单栏(登录、管理员、教师、学生) | 图 6-1、6-2,代码片段 |
LoginForm.cs | 独立登录窗体,验证用户名密码后创建对应角色连接 | 报告未提,但必须存在 |
StudentInfo.cs | 学生信息管理窗体,含 DataGridView 绑定Student表 | menuItem3_Click调用 |
CourseElect.cs | 学生选课窗体,含课程列表 DataGrid 和“选课”按钮 | 图 6-3,代码片段 |
App.config | 配置文件,存数据库连接字符串(不能硬编码在代码里) | 报告未提 |
关键操作:
- 新建工程时选Windows Forms Application,.NET Framework 版本选3.5(兼容 SQL Server 2000);
App.config中添加:<configuration> <appSettings> <add key="ConnStr" value="server=localhost;database=eisbook;uid={0};pwd={1};" /> </appSettings> </configuration>
- 登录后,用
string.Format(ConfigurationManager.AppSettings["ConnStr"], username, password)拼连接字符串。
5.2 数据库连接失败的五大排查路径
这是新手 90% 的卡点,按顺序查:
SQL Server 服务没开:
- Win+R →
services.msc→ 找SQL Server (MSSQLSERVER)→ 状态是否“正在运行”?没开就右键“启动”。
- Win+R →
数据库名写错:
- 连接字符串里
database=eisbook,但 SQL Server Management Studio 里实际数据库名是EISBOOK或eisbook_db?大小写敏感?用 SSMS 刷新确认。
- 连接字符串里
用户无数据库访问权:
- SSMS 登录
eisbook数据库 → 安全性 → 用户 → 右键你的用户名(如jiaowuyuan)→ 属性 → “用户映射” → 勾选eisbook数据库 → 角色成员中勾选db_datareader,db_datawriter(教务员还需db_owner)。
- SSMS 登录
TCP/IP 协议未启用:
- SQL Server 配置管理器 → SQL Server 网络配置 → MSSQLSERVER 的协议 → 右键
TCP/IP→ 启用 → 重启服务。
- SQL Server 配置管理器 → SQL Server 网络配置 → MSSQLSERVER 的协议 → 右键
防火墙拦截:
- 控制面板 → Windows Defender 防火墙 → 允许应用通过防火墙 → 勾选
SQL Server (MSSQLSERVER)。
- 控制面板 → Windows Defender 防火墙 → 允许应用通过防火墙 → 勾选
5.3 DataGridView 绑定数据源的正确姿势
报告图 6-3 的dataGrid1.DataSource=this.electTable;是典型错误写法——electTable是 DataSet 的 Table,但没填充数据。正确流程:
// 在 CourseElect_Load 事件中 private void CourseElect_Load(object sender, EventArgs e) { // 1. 创建数据适配器(用教务员账号连,因学生不能查课程表) string connStr = "server=localhost;database=eisbook;uid=jiaowuyuan;pwd=pwd123;"; SqlConnection conn = new SqlConnection(connStr); SqlDataAdapter da = new SqlDataAdapter( "SELECT Cno, Cname, Credit, Cnum FROM Course WHERE CourseType='必修'", conn); // 2. 创建 DataSet 并填充 DataSet ds = new DataSet(); da.Fill(ds, "Course"); // 填充到 ds.Tables["Course"] // 3. 绑定到 DataGrid(不是直接绑 Table) dataGrid1.DataSource = ds.Tables["Course"]; // 4. (可选)隐藏不需要的列 dataGrid1.Columns["Cno"].Visible = false; // 课序号不显示给学生 }逻辑说明:
- 学生选课窗体查课程,必须用教务员账号(因
Course表权限给了role_jiaowuyuan),不能用学生账号;Fill()后ds.Tables["Course"]才有数据,直接this.electTable是 null;DataGrid绑定DataTable,不是DataSet。
5.4 部署到其他电脑:三步打包,拒绝“在我机器上好好的”
发布数据库:
- SSMS 右键
eisbook数据库 → 任务 → 生成脚本 → “编写整个数据库的数据和架构” → 保存为eisbook.sql; - 目标电脑装好 SQL Server,执行
eisbook.sql创建库和表。
- SSMS 右键
发布应用程序:
- Visual Studio → 生成 → 发布 → 选择文件夹 → 下一步 → 完成;
- 生成的
Application Files文件夹复制到目标电脑。
配置目标电脑:
- 安装 .NET Framework 3.5(Win10 默认不装,需控制面板启用);
- 修改
App.config中的连接字符串,指向目标电脑的 SQL Server(server=目标IP); - 运行
setup.exe安装。
血泪经验:
- 绝对不要用
localhost写死在App.config里,部署到局域网其他机器时,必须改成server=192.168.1.100;- 如果目标电脑没装 SQL Server,宁可放弃,也不要尝试用 SQLite 替代——那会彻底偏离课程设计要求的“数据库技术应用”。
6. 我的验证清单:每次交付前必跑的七条 SQL 与三个界面操作
这不是一个“做完就扔”的课程设计,而是一个需要向老师证明“它真能用”的作品。从那以后我每次交作业,都强制走一遍这个清单,没一次被问倒过。希望帮到你。
6.1 数据库层验证:七条 SQL,覆盖核心业务
把下面七条 SQL 复制到 SSMS,逐条执行,全部返回预期结果才算过关:
-- 1. 检查教务员能否看到所有学生(应返回 >0 行) SELECT COUNT(*) FROM Student; -- 2. 检查教师能否看到自己教的课(替换 Tno) SELECT * FROM Course WHERE Tno = 'T001'; -- 3. 检查学生能否看到自己选 <p> <a href="https://download.csdn.net/download/yunxidzh/23255554" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>