news 2026/9/11 5:35:14

SQL Server数据库实验大作业:从建库建表到存储过程与触发器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL Server数据库实验大作业:从建库建表到存储过程与触发器

简介:面向软件工程本科生的SQL Server数据库实验大作业,以小区物业收费管理系统为完整业务场景,覆盖业主、部门、员工、收费四类核心信息表的设计与实现。资源适合正在学习数据库原理、需要完成课程设计或综合实验的本科生,也可作为毕业设计初期的参考模板,帮助理解从需求分析、E-R建模到建库建表、查询视图、索引、权限管理等全流程数据库开发规范。压缩包共16个文件,约12.33MB,其中13个sql脚本分模块承载建表、插入、查询、视图、索引、授权及多用户操作;另含实验报告docx、E-R图pdf及可修改的vsd原图,便于对照文档与代码同步学习。配套报告和图示能直观展示表间关系与收费计算逻辑,尤其对物业费、卫生费、水费、电费的公式实现做了完整落地,可用于快速复用或二次开发。目前已有1427人学习浏览,适合需要完整可运行方案与书面报告支撑的数据库课程实践人群。

1. SQL Server 实验大作业的验收逻辑:从建库到报告一次跑通

拿到“学生选课管理系统”“图书馆借阅系统”这类数据库实验大作业题目,很多人的第一反应是去网上下载一套能直接跑的脚本。但实验报告那一栏不会让你白写,代码和文档对不上的作业,恰恰是扣分最重的地方。一个典型的 Microsoft SQL Server 大作业,验收时老师看三件事:建表语句能不能反推回需求分析、增删改查有没有覆盖业务规则、报告里对查询结果和约束冲突有没有解释。也就是说,这份作业真正在训练的不是“能不能跑通”,而是“你能不能讲清楚 SQL Server 是怎么把业务模型变成物理表的”。这篇文章按做数据库课程设计最常见的落地顺序展开:从 CREATE DATABASE 与约束设计,到增删改查、视图、存储过程、触发器,最后落在实验报告交之前的验证技巧上。新手可以直接照步骤复现,有经验的人也能在这些环节里找到自己平时容易含糊的参数和边界。

2. 建库与建表:从业务规则到带约束的 CREATE TABLE

2.1 先定主键与关系:写 CREATE TABLE 之前要拍板的三个问题

课程设计的题目虽然各不相同,设计阶段要做的决定大同小异。第一个是主键选型:用自增 IDENTITY 还是自然键。像学生表,学号看似唯一,但实验作业里我建议保留自增的学生表主键,同时给学号加 UNIQUE 约束。这样成绩表引用的主键稳定,学号变更也不会波及成百上千条选课记录。这个决策本身就该写进实验报告“数据库设计”一节,体现你区分了代理键与自然键。

第二个是关系和删除策略。选课表是典型的多对多关系,中间表的主键通常是两个外键的复合主键。删除策略这时就要想清楚:删学生时,选课记录怎么办。实验环境里多用ON DELETE CASCADE,但不建议每个外键都级联。比如课程表被成绩表引用时,如果误删一门课,级联会把成绩也清掉,放在实验场景里反而不好交代数据完整性。第三个是约束的粒度。性别只允许“男”“女”,成绩在 0 到 100 之间,入学年份有合理范围,这些能用 CHECK 表达的规则尽量写进表定义。等报告写“数据完整性设计”时,这段建表语句就是你最硬的论据。

2.2 CREATE DATABASE:实验库的文件参数也要交代得清

很多实验报告在“数据库实现”里只写一句“新建了数据库”,这是不够的。把文件组、初始大小、自动增长写进脚本,老师能看到你理解数据库不是一张表那么简单。下面的脚本适合大多数 5 万行以内的课程设计数据量。

USE master; GO IF DB_ID(N'CourseDesignDB') IS NOT NULL BEGIN ALTER DATABASE CourseDesignDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE CourseDesignDB; END; GO CREATE DATABASE CourseDesignDB ON PRIMARY ( NAME = N'CourseDesignDB_Data', FILENAME = N'D:\SQLData\CourseDesignDB.mdf', SIZE = 16MB, MAXSIZE = 512MB, FILEGROWTH = 8MB ) LOG ON ( NAME = N'CourseDesignDB_Log', FILENAME = N'D:\SQLData\CourseDesignDB_log.ldf', SIZE = 8MB, MAXSIZE = 256MB, FILEGROWTH = 4MB ); GO

脚本前半部分处理“数据库已存在”的情况,先改成单用户再删库,方便你反复调试建库脚本。ON PRIMARY指定数据文件放主文件组,FILEGROWTH用固定兆数而不是百分比,是为了避免日志文件增长过快把磁盘占满。实验报告里可以补一句:数据文件 16MB 起步按 8MB 增长,日志文件 8MB 起步按 4MB 增长,这是针对中小数据量做的保守配置。如果你用的是 SQL Server Express 版本,注意数据库上限是 10GB,别把MAXSIZE设得让脚本在其他机器上跑不起来。

2.3 用 CREATE TABLE 一次写全:PK、FK、CHECK、DEFAULT 与唯一约束

建表脚本要能体现实体完整性与参照完整性。学生表、课程表、选课表三张表建完后,彼此之间通过外键形成完整的关系网。

USE CourseDesignDB; GO CREATE TABLE dbo.Student ( StudentID INT IDENTITY(1001, 1) NOT NULL, StudentNo NVARCHAR(12) NOT NULL, StudentName NVARCHAR(20) NOT NULL, Gender NCHAR(1) NOT NULL, BirthDate DATE NULL, Major NVARCHAR(30) NULL, EnrollmentYear SMALLINT NULL, CONSTRAINT PK_Student PRIMARY KEY (StudentID), CONSTRAINT UQ_Student_StudentNo UNIQUE (StudentNo), CONSTRAINT CK_Student_Gender CHECK (Gender IN (N'男', N'女')), CONSTRAINT CK_Student_BirthDate CHECK (BirthDate <= GETDATE()) ); GO CREATE TABLE dbo.Course ( CourseID INT IDENTITY(1, 1) NOT NULL, CourseNo NVARCHAR(10) NOT NULL, CourseName NVARCHAR(40) NOT NULL, Credit TINYINT NOT NULL, CONSTRAINT PK_Course PRIMARY KEY (CourseID), CONSTRAINT UQ_Course_CourseNo UNIQUE (CourseNo), CONSTRAINT CK_Course_Credit CHECK (Credit BETWEEN 1 AND 10) ); GO CREATE TABLE dbo.StudentCourse ( StudentID INT NOT NULL, CourseID INT NOT NULL, Score DECIMAL(5, 2) NULL, RegisterDate DATE NOT NULL, CONSTRAINT PK_StudentCourse PRIMARY KEY (StudentID, CourseID), CONSTRAINT FK_StudentCourse_Student FOREIGN KEY (StudentID) REFERENCES dbo.Student (StudentID) ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT FK_StudentCourse_Course FOREIGN KEY (CourseID) REFERENCES dbo.Course (CourseID) ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT CK_StudentCourse_Score CHECK (Score >= 0 AND Score <= 100) ); GO

选课表用(StudentID, CourseID)做复合主键,保证同一个学生不能重复选同一门课。DECIMAL(5, 2)是成绩字段的常见选择,最高 999.99,容纳百分制足够了。StudentCourse的 Score 允许 NULL,因为选课行为发生在前,成绩录入在后,这个 NULL 是有业务含义的,不是设计缺陷。

注意学生表里的两个 CHECK 约束。BirthDate <= GETDATE()防止录错未来日期,性别约束限定两个合法值。把它们声明成带名字的约束而不是匿名约束,是为了后面用ALTER TABLE ... DROP CONSTRAINT时能准确找到目标。

2.4 约束冲突时的报错规律:2627 与 547 分别从哪里来

写实验报告时,指导老师经常追问“约束报错了怎么办”。与其毫无头绪地改,不如记住 SQL Server 的一组典型错误范围。出现 2627 错误,基本是主键或唯一约束冲突,也就是你要插入的键值已经存在;出现 547 错误,则分两种情况:要么是外键引用的父表行不存在,要么是 CHECK 约束检查没通过。

约束类型常见错误号排查切入点
PRIMARY KEY / UNIQUE2627检查自增列是否被手工指定了重复值,或业务键重复
FOREIGN KEY547被参照行是否存在;删除父表行前是否还有子记录指向它
CHECK547插入值与限定范围对照,注意 NULL 默认会通过 CHECK 检查
DEFAULT看事件探查器或默认值绑定是否正确
索引键宽度超出1701索引键列总长度超过 900 字节,多见于 NVARCHAR 过长

修改约束本身也是个实验报告可以写的操作,语法如下。

ALTER TABLE dbo.Student DROP CONSTRAINT CK_Student_BirthDate; GO ALTER TABLE dbo.Student ADD CONSTRAINT CK_Student_BirthDate CHECK (BirthDate >= '1990-01-01' AND BirthDate <= GETDATE()); GO

DROP CONSTRAINTADD CONSTRAINT是 SQL Server 改约束的标准姿势。没有ALTER CONSTRAINT这样的命令,改规则本质上就是先删后建。如果你在本机设置过数据库兼容级别,记得用ALTER DATABASE CourseDesignDB SET COMPATIBILITY_LEVEL保持与目标环境一致,避免语法或行为上的差异导致作业在其他机器上验收失败。

3. 数据操纵与事务:把增删改查做成一整套业务闭环

3.1 INSERT 的四种写法差异:多行、子查询与 BULK 导入

实验报告里的“数据操纵”环节,不能只交一个INSERT INTO ... VALUES。常见作业要求的数据来源有四类:手工录入、批量模拟数据、从已有表迁移、外部文件导入。不同来源对应不同写法。

-- 多行 VALUES,SQL Server 2008 之后支持 INSERT INTO dbo.Student (StudentNo, StudentName, Gender, BirthDate, Major, EnrollmentYear) OUTPUT INSERTED.StudentID, INSERTED.StudentNo VALUES (N'2024010101', N'王敏', N'女', '2004-03-15', N'软件工程', 2024), (N'2024010102', N'刘洋', N'男', '2004-07-02', N'软件工程', 2024);

OUTPUT子句可以立刻拿到新生成的 IDENTITY 值。这个技巧在做“新生报到—自动选必修课”的流程里尤其有用,否则你还得再查一次学号才能拿到自增 ID。多行 VALUES 一次最多 1000 行,超过就拆批或者换下面这种方式。

-- 从临时表迁移,配合 NOT EXISTS 做到幂等 SELECT * INTO #NewStudents FROM ( SELECT N'2024010199' AS StudentNo, N'赵强' AS StudentName, N'男' AS Gender UNION ALL SELECT N'2024010200', N'孙丽', N'女' ) AS t; INSERT INTO dbo.Student (StudentNo, StudentName, Gender) SELECT StudentNo, StudentName, Gender FROM #NewStudents AS t WHERE NOT EXISTS (SELECT 1 FROM dbo.Student s WHERE s.StudentNo = t.StudentNo);

SELECT INTO #NewStudents创建临时表,UNION ALL模拟一批待导入数据,NOT EXISTS判断学号是否已存在。这套写法在数据量几千行时性能足够,也不会因为重复执行产生脏数据。如果外部文件是 CSV,常用BULK INSERT或数据导入向导,注意 CSV 里的中文编码要用带 BOM 的 UTF-8,否则 NVARCHAR 字段导入后会出现乱码。

3.2 UPDATE 与 DELETE:连带更新和级联删除的边界

UPDATE 最容易被忽略的是“影响行数”。实验作业里常有一个需求:把某门课所有不及格的成绩改成 60 分并加备注。此时不只是改成绩表,业务上可能还要联动修课程统计表。用事务包裹多个 UPDATE 才能保证一致。下面这段是常见的评分调整逻辑。

BEGIN TRY BEGIN TRANSACTION; UPDATE dbo.StudentCourse SET Score = 60 WHERE CourseID = (SELECT CourseID FROM dbo.Course WHERE CourseNo = N'CS101') AND Score < 60; UPDATE dbo.Course SET Credit = Credit WHERE CourseID = (SELECT CourseID FROM dbo.Course WHERE CourseNo = N'CS101'); COMMIT TRANSACTION; END TRY BEGIN CATCH ROLLBACK TRANSACTION; THROW; END CATCH;

第二句 UPDATE 看起来没实际作用,但它是为了给实验报告展示“成绩调整后,课程统计记录应该同步更新”的完整流程。THROW把错误信息原样抛给调用方,比旧式的RAISERROR更容易保留原始错误号。删除操作上要注意级联删除的实际范围,ON DELETE CASCADE不是万能的,如果外键列是复合主键的一部分,级联链路会一层层传递,删除学生可能会连带删掉选课记录,这是设计阶段就该预判的行为。

3.3 查询数据库:聚合、分组与窗口函数的组合方式

实验作业里的 SELECT 查询通常不是单表查询,而是老师指定“统计每门课选课人数、平均分、最高分及排名”。这里用 GROUP BY 配聚合函数是及格标准,窗口函数则是拉开差距的部分。

SELECT c.CourseName, COUNT(sc.StudentID) AS CourseCount, CAST(AVG(sc.Score) AS DECIMAL(5, 2)) AS AvgScore, MAX(sc.Score) AS MaxScore, RANK() OVER (ORDER BY AVG(sc.Score) DESC) AS RankByAvg FROM dbo.Course c LEFT JOIN dbo.StudentCourse sc ON c.CourseID = sc.CourseID GROUP BY c.CourseID, c.CourseName HAVING COUNT(sc.StudentID) >= 1 ORDER BY RankByAvg;

LEFT JOIN保住没有学生选修的课程,HAVING过滤掉没有选课记录的课程,RANK()窗口按平均分给课程排名。注意GROUP BY里写了c.CourseID, c.CourseName,这是 SQL Server 的语法要求,SELECT 里出现的非聚合列必须出现在 GROUP BY 中。如果只对特定课程内部排名,用PARTITION BY就行。

SELECT s.StudentName, c.CourseName, sc.Score, ROW_NUMBER() OVER (PARTITION BY c.CourseID ORDER BY sc.Score DESC) AS SeqInCourse FROM dbo.StudentCourse sc JOIN dbo.Student s ON sc.StudentID = s.StudentID JOIN dbo.Course c ON sc.CourseID = c.CourseID;

ROW_NUMBER在每个课程分区内按成绩降序编号,可以用来筛每门课的前三名。这个查询直接搬进实验报告,配合执行计划截图,比单纯贴一个 JOIN 结果要有说服力。

3.4 事务与并发控制:BEGIN TRAN 不是表演

很多人写完增删改查就以为完成了大作业核心,但数据库课程设计里事务是不可少的考察点。老师常会问:两个学生同时选修同一门课,你的表能扛住吗?复合主键已经挡住了重复选课,但如果是“先检查再插入”的流程,并发下仍然有漏洞。用事务加约束才是一套完整的应对方案。

DECLARE @StudentNo NVARCHAR(12) = N'2024010199'; DECLARE @CourseNo NVARCHAR(10) = N'CS101'; BEGIN TRY BEGIN TRANSACTION; IF NOT EXISTS ( SELECT 1 FROM dbo.StudentCourse sc JOIN dbo.Student s ON sc.StudentID = s.StudentID JOIN dbo.Course c ON sc.CourseID = c.CourseID WHERE s.StudentNo = @StudentNo AND c.CourseNo = @CourseNo ) BEGIN INSERT INTO dbo.StudentCourse (StudentID, CourseID, RegisterDate) SELECT s.StudentID, c.CourseID, GETDATE() FROM dbo.Student s, dbo.Course c WHERE s.StudentNo = @StudentNo AND c.CourseNo = @CourseNo; END; COMMIT TRANSACTION; END TRY BEGIN CATCH ROLLBACK TRANSACTION; THROW; END CATCH;

这段脚本把“检查存在—插入记录”放进显式事务,配合选课表的复合主键,双保险保证同一学号同一课程只能有一条记录。报告里可以补一句:SQL Server 默认隔离级别是 READ COMMITTED,这里靠的是约束兜底,并没有依赖锁,所以并发下依然可靠。如果想让并发更稳,可以在应用层改为先捕获 2627 错误再走更新流程。

4. 视图、存储过程、触发器与索引:实验报告的核心得分区

4.1 视图:定义统计口径而不是拷贝数据

实验作业里视图最常见的用途是给报告提供“统一查询口径”。比如“学生成绩汇总视图”既要展示每名学生的选课门数,又要算平均分,这类逻辑用视图定义一次,后面所有查询都引用视图即可。注意一点:普通视图不存数据,它只是一段保存的 SELECT,每次查询都重新执行。

CREATE OR ALTER VIEW vStudentScoreSummary WITH SCHEMABINDING AS SELECT s.StudentNo, s.StudentName, COUNT_BIG(*) AS CourseCount, AVG(sc.Score) AS AvgScore FROM dbo.Student s JOIN dbo.StudentCourse sc ON s.StudentID = sc.StudentID GROUP BY s.StudentNo, s.StudentName; GO

WITH SCHEMABINDING让视图与底层表结构绑定,防止你或他人直接修改或删除被引用的表和列。加了 SCHEMABINDING 后,聚合函数必须写成COUNT_BIG(*),这是 SQL Server 对索引视图的硬性要求。实验报告里写“视图绑定架构以保障引用完整性”就是加分项。视图也可以用CREATE OR ALTER直接覆盖更新,实验调试期省去先 DROP 再 CREATE 的麻烦。

4.2 存储过程:参数校验与 RAISERROR 的课堂模板

存储过程是大作业里体现“业务封装”的核心对象。一个加选课信息的存储过程,要同时做参数校验、判断学生是否存在、判断课程是否存在、捕获冲突四个步骤。下面这个模板可以适配大多数“增删改查”类课程设计。

CREATE OR ALTER PROCEDURE dbo.usp_AddStudentCourse @StudentNo NVARCHAR(12), @CourseNo NVARCHAR(10), @Score DECIMAL(5, 2) = NULL AS BEGIN SET NOCOUNT ON; DECLARE @StudentID INT; DECLARE @CourseID INT; SELECT @StudentID = StudentID FROM dbo.Student WHERE StudentNo = @StudentNo; IF @StudentID IS NULL BEGIN RAISERROR(N'学号 %s 不存在', 16, 1, @StudentNo); RETURN; END; SELECT @CourseID = CourseID FROM dbo.Course WHERE CourseNo = @CourseNo; IF @CourseID IS NULL BEGIN RAISERROR(N'课程号 %s 不存在', 16, 1, @CourseNo); RETURN; END; IF EXISTS (SELECT 1 FROM dbo.StudentCourse WHERE StudentID = @StudentID AND CourseID = @CourseID) BEGIN RAISERROR(N'该生已选修过此课程', 16, 1); RETURN; END; INSERT INTO dbo.StudentCourse (StudentID, CourseID, Score, RegisterDate) VALUES (@StudentID, @CourseID, @Score, GETDATE()); END; GO

SET NOCOUNT ON关掉“受影响行数”的提示,减少不必要的网络流量。RAISERROR的第二个参数 16 表示严重级别,第三个参数 1 是状态码,后面的@StudentNo对应消息中的%s占位符。调用时直接用EXEC dbo.usp_AddStudentCourse N'2024010199', N'CS101';。报告中还可以写一行:带RETURN的提前退出,避免了嵌套 IF ELSE 把逻辑绕晕。

4.3 触发器:AFTER 审计触发器与 INSTEAD OF 的门槛问题

触发器是最容易出现“想当然”错误的地方。评分修改记录很适合用 AFTER UPDATE 触发器做审计,它把旧值和新值分别放进 DELETED 与 INSERTED 虚拟表,两者结构完全一致。

CREATE TABLE dbo.ScoreChangeLog ( LogID INT IDENTITY(1, 1) PRIMARY KEY, StudentID INT NOT NULL, CourseID INT NOT NULL, OldScore DECIMAL(5, 2) NULL, NewScore DECIMAL(5, 2) NULL, ChangedBy NVARCHAR(128) NULL, ChangedAt DATETIME2(0) NULL ); GO CREATE OR ALTER TRIGGER trg_StudentCourse_AuditScore ON dbo.StudentCourse AFTER UPDATE AS BEGIN SET NOCOUNT ON; IF UPDATE (Score) BEGIN INSERT INTO dbo.ScoreChangeLog (StudentID, CourseID, OldScore, NewScore, ChangedBy, ChangedAt) SELECT i.StudentID, i.CourseID, d.Score, i.Score, SUSER_SNAME(), GETDATE() FROM INSERTED i JOIN DELETED d ON i.StudentID = d.StudentID AND i.CourseID = d.CourseID; END; END; GO

UPDATE (Score)判断本次 UPDATE 语句是否涉及 Score 列,避免任何原值与新值相同的无效记录。SUSER_SNAME()记录当前登录名,GETDATE()记录修改时间。这个触发器只响应 UPDATE,INSERT 不触发,如果你希望首次录入成绩也留痕,可以把AFTER UPDATE改成AFTER INSERT, UPDATE,逻辑不变。

INSTEAD OF触发器的典型场景是“对视图做限制”。例如不允许直接向统计视图插入数据:

CREATE OR ALTER TRIGGER trg_vStudentScoreSummary_NoDirectInsert ON vStudentScoreSummary INSTEAD OF INSERT AS BEGIN SET NOCOUNT ON; RAISERROR(N'统计视图不允许插入数据,请通过业务表维护', 16, 1); END; GO

作业里不需要写太多触发器,一个审计触发器加一个限制视图写操作的触发器就够撑起“数据安全与自动化”这一节了。

4.4 索引:实验报告里最能拉开差距的设计

索引部分建议从“缺失索引提示”入手,回头改表。SQL Server 查询分析器会记录缺失索引的建议,在查询成绩按分数范围筛选的场景下跑一次,再用下面的 DMV 查询拿具体建议。

SELECT mid.statement, mid.equality_columns, mid.inequality_columns, mid.included_columns FROM sys.dm_db_missing_index_details mid ORDER BY mid.statement;

基于建议创建针对成绩查询的覆盖索引:

CREATE NONCLUSTERED INDEX IX_StudentCourse_Course_Score ON dbo.StudentCourse (CourseID, Score) INCLUDE (StudentID);

INCLUDE列不参与索引排序,只作为覆盖列挂在叶级,避免查询需要回表。(CourseID, Score)的列顺序也很讲究:先等于匹配(CourseID),后范围查询(Score),能让索引扫描范围尽量小。报告里写索引设计时,把执行计划里的 Index Seek 改为 Index Scan 的前后对比例图放进去,说服力立刻不一样。

5. 实验报告交之前:用系统视图与执行计划给结果留证据

5.1 用 DBCC CHECKCONSTRAINTS 与系统视图核对完整性

报告结论里写“所有约束验证通过”之前,先实际跑一遍检查。DBCC CHECKCONSTRAINTS会逐表核对约束是否有违反的行。

DBCC CHECKCONSTRAINTS (CourseDesignDB); GO

如果检查通过,结果是空结果集;如果存在违规数据,会返回表名、约束名和具体违规行。把所有外键、检查约束、默认约束列成清单也能作为报告的附录。用系统视图生成约束列表,不是拍脑袋写出来的:

SELECT t.name AS TableName, c.name AS ConstraintName, c.type_desc AS ConstraintType FROM sys.tables t JOIN sys.objects c ON t.object_id = c.parent_object_id WHERE c.type IN ('PK', 'F', 'C', 'UQ') ORDER BY t.name, c.type_desc;

type对应的含义依次是主键、外键、检查约束、唯一约束。这张表可以直接导出成报告附表,展示你数据库里到底建了哪些规则。

5.2 用 SET STATISTICS IO 与执行计划给查询留下对比数据

实验报告的查询分析小节,最怕写“执行时间 0.001 秒”这种没有上下文的数据。正确做法是开语句级统计信息,记录逻辑读取次数和 CPU 时间。

SET STATISTICS IO ON; SET STATISTICS TIME ON; GO SELECT c.CourseName, COUNT(sc.StudentID) AS CourseCount, AVG(sc.Score) AS AvgScore FROM dbo.Course c JOIN dbo.StudentCourse sc ON c.CourseID = sc.CourseID GROUP BY c.CourseID, c.CourseName ORDER BY CourseCount DESC; GO SET STATISTICS IO OFF; SET STATISTICS TIME OFF;

打开统计后,消息选项卡里会多出“表 'StudentCourse'。扫描计数 1,逻辑读取 12 次”这样的输出。报告里写“对 StudentCourse 覆盖索引后逻辑读取从 87 次降到 12 次”,比写十句“性能提升”都管用。同时,在 SSMS 里勾选“包含实际执行计划”,截图时把执行计划与消息窗口放在同一张图,保证数据可溯源。

5.3 附录的组织技巧:代码、结果与页数的对应关系

最后提一个交作业最容易吃亏的地方:报告附录和大作业代码的组织。数据库实验大作业通常要求“包含代码及实验报告”,这里的代码不能是乱七八糟的.bak文件或一个难以阅读的.sql文件。我会把脚本按顺序拆成文件夹:01_建库建表、02_基础数据、03_视图存储过程触发器、04_查询验证、05_清理脚本,每个脚本文件头部写一行注释说明运行顺序。报告附录里只放核心代码的截取版本,建表语句可以完整放,几十行数据 INSERT 就别贴了,写“共 200 行,见附录代码 02_基础数据.sql”就行。这样做既控制报告页数,也让验收老师能在数据库里回放你的全部实现过程。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 5:31:11

Redis缓存击穿解决方案:双重判定锁原理与SpringBoot实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 5:30:29

异步消息驱动架构改造实战:从同步网关到高可用消息链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 5:29:36

render-middleware:为 Remix 路由注入请求级渲染器的中间件包解析

render-middleware&#xff1a;为 Remix 路由注入请求级渲染器的中间件包解析 【免费下载链接】remix The fully-stacked web framework 项目地址: https://gitcode.com/GitHub_Trending/re/remix remix-run/render-middleware 是 Remix 全栈框架中负责"请求级响应…

作者头像 李华
网站建设 2026/9/11 5:26:53

ESP32双屏GIF稳定播放的SPI与LVGL协同设计

1. 为什么“能播放”不等于“能扛住八小时”&#xff1a;一个被低估的嵌入式显示稳定性陷阱刚把GIF在ESP32双屏上跑起来那会儿&#xff0c;我拍着桌子跟同事说&#xff1a;“成了&#xff01;”——主屏滚动文字&#xff0c;副屏循环播放一个12864像素的齿轮转动GIF&#xff0c…

作者头像 李华