拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

南华大学数据库原理实验报告:SQL Server建库、查询、存储过程与游标全流程

南华大学数据库原理实验报告:SQL Server建库、查询、存储过程与游标全流程

简介:这份南华大学《数据库原理》实验报告面向大数据技术等专业学生,用于巩固数据库管理系统认识与SQL语言应用,适合课程实验提交参考、期末复习及SQL入门练习。报告围绕SQL Server Management Studio展开,涵盖数据库与数据表的创建、主码外码与默认值设定、表间一对多及多对多关系构建,并系统梳理单表查询与多表连接查询的SELECT、JOIN用法,涉及条件筛选、排序、分组及间接先行课等典型题目,同时体现数据完整性与基本数据更新操作。资源包共1个doc文件,约5.38MB,内容为完整实验报告文档,含实验题目、要求、代码与总结,目录按实验1至实验4及实验总结编排,便于按模块查阅。目前已有374人学习下载,可帮助读者对照题目理解建库建表思路、掌握查询语句写法并查漏补缺。

1. 南华大学数据库原理实验报告:从建库到游标的六个必做关卡

南华大学数据库原理实验报告这门课,真正要交的不是一份文档,而是一条能跑通的链路:装好 SQL Server、建库建表、写 SELECT 查询、写存储过程、用游标处理逐行逻辑,最后把每一步截图和 SQL 语句整理成报告。很多同学卡住的地方不是 SQL 语法本身,而是环境没配对、约束没加对、游标写完不知道结果对不对。这篇笔记按实验报告里最常见的六个关卡来拆,每一关都给可复现的 SQL 和参数说明,目标是让你照着敲一遍就能把实验做完,而不是对着 DBMS 概念发呆。适合正在上数据库原理课、需要交实验报告,或者想用 SQL Server 把课本例子跑一遍的人。

2. 实验环境准备:SQL Server 安装与 SSMS 连接

2.1 版本选择与安装路径

数据库原理实验对版本要求不高,SQL Server 2019 或 2022 的 Developer 版就够用,功能和企业版一致,只是授权范围不同。安装时实例名建议用默认实例MSSQLSERVER,因为实验指导书里的连接字符串通常写的是localhost或.,用命名实例反而要多写一段localhost\SQLEXPRESS,容易在报告里写错。

安装过程中身份验证模式选“混合模式”,并给sa设一个密码。这一步很多同学跳过,结果后面用 JDBC 或 Python 连接时只能走 Windows 身份验证,换台机器就翻车。混合模式下 SQL Server 身份验证和 Windows 身份验证都能用,实验报告里写连接方式也灵活。

装完之后装 SSMS(SQL Server Management Studio),这是写查询和截图的主要工具。SSMS 版本可以和数据库引擎版本不一致,比如 SSMS 19 连 SQL Server 2019 完全没问题,不需要版本号严格对齐。

2.2 连接失败的三类排查

连接不上是实验第一道坎,报错信息通常分三类。

第一类是“无法连接到服务器”,先看 SQL Server 服务有没有启动。在“服务”里找SQL Server (MSSQLSERVER),状态应该是“正在运行”。如果是手动启动,改成自动,否则每次重启电脑都要手动开一次。

第二类是“登录失败”,如果用sa登录,确认混合模式已启用,并且sa账户没有被禁用。可以在 SSMS 里用 Windows 身份验证登录后执行:

ALTER LOGIN sa ENABLE; ALTER LOGIN sa WITH PASSWORD = 'YourStrongPassword123';

这两句分别启用sa账户和重设密码。密码要满足复杂度要求,太简单的密码 SQL Server 会拒绝。

第三类是 SSL 加密相关报错,常见于旧版驱动连接新版 SQL Server。解决办法是在连接字符串里加TrustServerCertificate=True,或者安装较新的 JDBC/ODBC 驱动。实验报告里如果只在本机用 SSMS,一般不会遇到这个问题,但用 Java 或 Python 做实验扩展时会碰到。

提示:安装完成后先重启一次电脑,再启动 SSMS 连接,能避免一半的“服务未启动”问题。

3. 建库建表:约束、默认值与主外键的写法

3.1 建库与建表的基本骨架

实验报告通常要求建一个“学生选课”或“图书管理”数据库。以学生选课为例,建库语句:

CREATE DATABASE StudentCourse; GO USE StudentCourse; GO

GO是 SSMS 的批处理分隔符,不是 SQL 语句的一部分,但实验报告里要写,因为多条语句一起执行时需要它来分批。

建表时把主键、外键、非空、唯一、默认值、CHECK 约束都加上,这是实验报告评分点。学生表:

CREATE TABLE Student ( Sno CHAR(10) PRIMARY KEY, Sname NVARCHAR(20) NOT NULL, Ssex NCHAR(1) CHECK (Ssex IN ('男','女')), Sage INT CHECK (Sage BETWEEN 15 AND 60), Sdept NVARCHAR(30) DEFAULT '计算机学院' );

CHAR(10)固定长度适合学号这种长度固定的字段,NVARCHAR适合姓名和院系,因为可能包含中文。CHECK约束在插入数据时就会拦截非法值,比在应用层判断更可靠。

选课表:

CREATE TABLE SC ( Sno CHAR(10), Cno CHAR(10), Grade DECIMAL(5,1) CHECK (Grade BETWEEN 0 AND 100), PRIMARY KEY (Sno, Cno), FOREIGN KEY (Sno) REFERENCES Student(Sno), FOREIGN KEY (Cno) REFERENCES Course(Cno) );

PRIMARY KEY (Sno, Cno)是复合主键,保证一个学生同一门课只有一条选课记录。外键分别指向学生表和课程表,删除学生时如果还有选课记录,默认会报错,这正好用来演示参照完整性。

3.2 默认值用 GUID 还是自增

热搜里有人问“sql 默认值 guid”,在 SQL Server 里可以用NEWID()生成 GUID 作为默认值:

CREATE TABLE LogTable ( LogID UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY, LogTime DATETIME DEFAULT GETDATE(), Content NVARCHAR(200) );

GUID 的好处是全局唯一,适合分布式场景;坏处是占 16 字节,作为聚集索引时插入性能比自增列差。实验报告里如果只是演示默认值,用NEWID()没问题,但生产环境一般用IDENTITY(1,1)自增列。这个取舍可以在报告的“实验分析”部分写一句,能体现你理解了两者的差别。

3.3 插入数据与约束验证

插入数据时故意插一条违反 CHECK 约束的记录,看 SQL Server 报什么错,这个截图放进报告里能说明约束生效:

INSERT INTO Student (Sno, Sname, Ssex, Sage) VALUES ('2023001', '张三', '男', 20); INSERT INTO Student (Sno, Sname, Ssex, Sage) VALUES ('2023002', '李四', '女', 21); INSERT INTO Student (Sno, Sname, Ssex, Sage) VALUES ('2023003', '王五', '中', 22);

第三条会报错,因为Ssex只能是“男”或“女”。报错信息里会写The INSERT statement conflicted with the CHECK constraint,把这句话截图,说明你验证了约束。

4. SELECT 查询实验:从单表到多表连接的写法

4.1 单表查询与 WHERE 条件

SELECT 是实验报告里占篇幅最大的部分。单表查询先写最简单的:

SELECT Sname, Sage FROM Student WHERE Sdept = '计算机学院';

WHERE后面跟条件,字符串用单引号。如果要查年龄在 20 到 22 之间的:

SELECT Sname, Sage FROM Student WHERE Sage BETWEEN 20 AND 22;

BETWEEN包含边界值,等价于Sage >= 20 AND Sage <= 22。实验报告里可以两种写法都写,对比结果是否一致。

模糊查询用LIKE:

SELECT Sname FROM Student WHERE Sname LIKE '张%';

%匹配任意多个字符,_匹配一个字符。查姓张的学生用'张%',查名字第二个字是“三”的用'_三%'。

4.2 多表连接与 JOIN 的写法

多表连接是数据库原理实验的核心。查每个学生的选课成绩:

SELECT Student.Sname, Course.Cname, SC.Grade FROM Student JOIN SC ON Student.Sno = SC.Sno JOIN Course ON SC.Cno = Course.Cno WHERE SC.Grade IS NOT NULL ORDER BY SC.Grade DESC;

JOIN默认是INNER JOIN,只返回匹配上的行。如果要保留没有选课的学生,用LEFT JOIN:

SELECT Student.Sname, SC.Cno, SC.Grade FROM Student LEFT JOIN SC ON Student.Sno = SC.Sno;

没有选课的学生Cno和Grade会显示NULL。实验报告里通常要求同时写内连接和外连接,并解释结果差异。

4.3 分组聚合与 HAVING

查每门课的平均分:

SELECT Cno, AVG(Grade) AS AvgGrade, COUNT(*) AS StuCount FROM SC GROUP BY Cno HAVING AVG(Grade) >= 70;

GROUP BY按课程号分组,AVG和COUNT是聚合函数。HAVING是对分组后的结果过滤,WHERE是对分组前的行过滤,两者不能混用。实验报告里如果写错位置,比如把聚合条件写在WHERE里,SQL Server 会直接报错,这个报错也可以截图作为“常见错误”记录。

注意:SELECT列表里出现的非聚合列必须出现在GROUP BY里,否则报错。这是 SQL Server 的语法要求,和 MySQL 的宽松模式不同。

5. 存储过程与游标:逐行处理的实验写法

5.1 存储过程的基本结构

存储过程是实验报告里容易丢分的部分,因为语法细节多。创建一个查学生选课门数的存储过程:

CREATE PROCEDURE GetStudentCourseCount @Sno CHAR(10) AS BEGIN SELECT Student.Sname, COUNT(SC.Cno) AS CourseCount FROM Student LEFT JOIN SC ON Student.Sno = SC.Sno WHERE Student.Sno = @Sno GROUP BY Student.Sname; END;

@Sno是输入参数,调用时传学号:

EXEC GetStudentCourseCount @Sno = '2023001';

EXEC是执行存储过程的关键字。存储过程的好处是预编译、可复用、减少网络传输,实验报告里可以在“实验分析”部分写这几点。

5.2 游标的声明、打开、提取与关闭

游标用于逐行处理结果集,实验报告里通常要求用游标实现“逐条打印选课成绩”或“逐行更新”。完整流程:

DECLARE @Sno CHAR(10), @Cno CHAR(10), @Grade DECIMAL(5,1); DECLARE cur_score CURSOR FOR SELECT Sno, Cno, Grade FROM SC WHERE Grade IS NOT NULL; OPEN cur_score; FETCH NEXT FROM cur_score INTO @Sno, @Cno, @Grade; WHILE @@FETCH_STATUS = 0 BEGIN PRINT '学号:' + @Sno + ' 课程:' + @Cno + ' 成绩:' + CAST(@Grade AS VARCHAR(10)); FETCH NEXT FROM cur_score INTO @Sno, @Cno, @Grade; END; CLOSE cur_score; DEALLOCATE cur_score;

DECLARE声明游标并绑定查询,OPEN打开游标,FETCH NEXT取下一行到变量,@@FETCH_STATUS为 0 表示还有数据。WHILE循环里处理每一行,处理完再FETCH下一行。最后CLOSE关闭游标,DEALLOCATE释放资源。

实验报告里如果只写CLOSE不写DEALLOCATE,游标占用的内存不会释放,多次执行会报“游标已存在”。这个坑很多同学踩过,报告里可以写一句“必须成对出现”。

5.3 游标与集合操作的取舍

游标能逐行处理,但性能比集合操作差很多。比如“把所有不及格成绩加 5 分”,用 UPDATE 一句就够:

UPDATE SC SET Grade = Grade + 5 WHERE Grade < 60;

用游标要写十几行,而且锁的粒度更细,并发时更容易死锁。实验报告里如果要求用游标实现,就按游标写;如果只是演示,建议在报告里对比两种写法,说明“能用集合操作就不用游标”的原则。这个对比能体现你对数据库原理的理解,不是只会背语法。

6. 实验报告避坑:从截图到 SQL 语句的五个常见问题

6.1 截图不显示数据库名和结果行数

现象:报告里的截图只有查询结果,看不出是哪个数据库、哪张表。原因:SSMS 默认不显示数据库名,结果窗口也没开行数统计。解决:在 SSMS 里点“查询”菜单,勾选“在状态栏中显示数据库名”,结果窗口右下角会显示行数。截图时把这两处一起截进去,老师一看就知道你确实执行了。

6.2 中文乱码

现象:插入的中文姓名显示成问号。原因:建表时用了VARCHAR而不是NVARCHAR,或者插入时没加N前缀。解决:中文字段统一用NVARCHAR,插入时写N'张三'。如果已经建表,用ALTER TABLE改字段类型,但已有数据可能丢失,最好一开始就定好。

6.3 外键约束导致插入失败

现象:插入选课记录时报“外键冲突”。原因:学生表里没有这个学号,或者课程表里没有这个课程号。解决:先插学生和课程,再插选课。实验报告里按“学生→课程→选课”的顺序写插入语句,能避免这个问题。如果确实要插,先查一下SELECT * FROM Student WHERE Sno = '2023001'确认存在。

6.4 游标忘记 DEALLOCATE

现象:第二次执行游标代码时报“游标已存在”。原因:上次执行只CLOSE没DEALLOCATE。解决:在CLOSE后面加DEALLOCATE cur_score;。如果已经报错,执行DEALLOCATE cur_score;释放掉再重新跑。实验报告里把这两句写在一起,养成习惯。

6.5 存储过程修改后没重新编译

现象:改了存储过程里的 SQL,执行结果还是旧的。原因:SQL Server 缓存了执行计划。解决:执行EXEC sp_recompile 'GetStudentCourseCount';强制重新编译,或者用ALTER PROCEDURE而不是CREATE PROCEDURE来修改。实验报告里如果写“修改存储过程”,用ALTER更规范。

7. 用窗口函数和慢 SQL 排查把实验报告写出深度

实验报告如果只写到游标,分数大概中等。想拿高分,可以在最后一节加窗口函数和慢 SQL 排查,这两个是热搜里出现频率高、老师也认可的知识点。

窗口函数在 SQL Server 2012 及以上版本支持。查每个学生选课成绩的排名:

SELECT Sno, Cno, Grade, RANK() OVER (PARTITION BY Sno ORDER BY Grade DESC) AS GradeRank FROM SC WHERE Grade IS NOT NULL;

PARTITION BY Sno按学号分组,ORDER BY Grade DESC按成绩降序,RANK()给出排名。同一个学生成绩相同的课程会并列排名,下一个名次跳号。如果要连续排名用DENSE_RANK(),要唯一排名用ROW_NUMBER()。这三个函数的区别可以在报告里用一张小表对比:

函数相同成绩处理名次是否跳号
ROW_NUMBER按顺序编号不跳号
RANK并列跳号
DENSE_RANK并列不跳号

慢 SQL 排查在实验环境里用不上,但可以写进“实验分析”。SQL Server 里查最耗时的语句:

SELECT TOP 10 total_elapsed_time / execution_count AS AvgTime, execution_count, text FROM sys.dm_exec_query_stats CROSS APPLY sys.dm_exec_sql_text(sql_handle) ORDER BY AvgTime DESC;

sys.dm_exec_query_stats是动态管理视图,记录每条语句的执行统计。total_elapsed_time是总耗时,除以execution_count得到平均耗时。CROSS APPLY把sql_handle对应的 SQL 文本取出来。这个查询在实验报告里可以作为“性能分析”部分,说明你不仅会写 SQL,还知道怎么看执行开销。

索引对查询的影响也可以做一个简单对比。在SC表的Sno列上建索引:

CREATE INDEX IX_SC_Sno ON SC(Sno);

然后在 SSMS 里开启“包括实际执行计划”,对比建索引前后查SELECT * FROM SC WHERE Sno = '2023001'的执行计划。建索引前是“表扫描”,建索引后是“索引查找”。把两个执行计划截图放进报告,比只写文字有说服力。

我自己的习惯是:每做完一个实验,先把 SQL 语句按“建库→建表→插入→查询→存储过程→游标”的顺序存成一个.sql文件,再统一执行一遍,确认没有依赖问题。截图时把 SSMS 的“消息”窗口也截进去,能看到“命令已成功完成”和影响行数。这样交上去的报告,老师翻一遍就知道你是真跑过,不是抄的。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表