全部文章

DB Experiment

文章目录

以下是一套共 30 道数据库实验 (SYSU-DCS283) 期末考核题目示例,题目均基于所提供的 school 数据库表结构 (STUDENTS, TEACHERS, COURSES, CHOICES) 进行设计。每道题目包含简要描述、标准答案及解析,覆盖了数据查询(单表与多表连接)、数据操作(INSERT、UPDATE、DELETE)、表创建及约束、触发器和事务等主要内容。希望能帮助在复习和练习中全面掌握 SQL Server 的核心技能。


1. 创建新表并设置主键与唯一性约束

题目描述
在 school 数据库中,创建一个名为 Worker 的表,字段包括:

要求:

  1. 将 WID 作为主键。
  2. 为 Wname 添加唯一性约束。
  3. 限制 Wage 不超过 30。

标准答案

CREATE TABLE Worker (
WID INT NOT NULL PRIMARY KEY,
Wname CHAR(20) NOT NULL UNIQUE,
Wage INT CHECK (Wage <= 30),
Wgender CHAR(1)
);

解析

  1. PRIMARY KEY 关键字可直接在定义字段时声明,或在表最后统一声明。
  2. UNIQUE 关键字可为字段设置唯一性约束。
  3. CHECK 约束可限制字段的取值范围。

2. 简单查询 (单表)

题目描述
查询 STUDENTS 表中所有 grade 等于 2001 的学生姓名(sname),并按照 sid 升序排列输出。

标准答案

SELECT sname
FROM STUDENTS
WHERE grade = 2001
ORDER BY sid ASC;

解析


3. 简单查询 (单表,多字段)

题目描述
查询 TEACHERS 表中所有老师(tid、tname、email)的信息,并按照 salary 降序排列。

标准答案

SELECT tid, tname, email
FROM TEACHERS
ORDER BY salary DESC;

解析


4. 条件查询与别名

题目描述
查询 COURSES 表中课时 (hour) 大于 40 的课程编号 (cid) 和课程名称 (cname),并将查询结果中的字段起别名:课程编号 AS 课程代码、课程名称 AS 课程名称。

标准答案

SELECT cid AS 课程代码, cname AS 课程名称
FROM COURSES
WHERE hour > 40;

解析


5. 多表连接查询 (内连接)

题目描述
查询所有选课记录中(CHOICES 表)学生姓名、课程名称、成绩(score)。结果中应包含学生姓名 (STUDENTS 表的 sname) 与课程名称 (COURSES 表的 cname),且只显示有对应关系的行。

标准答案

SELECT S.sname, C.cname, CH.score
FROM CHOICES CH
INNER JOIN STUDENTS S ON CH.sid = S.sid
INNER JOIN COURSES C ON CH.cid = C.cid;

解析


6. 多表条件查询 (连接 + 条件)

题目描述
查询选修“C0001”课程且成绩大于 80 分的学生姓名及该课程成绩。

标准答案

SELECT S.sname, CH.score
FROM CHOICES CH
JOIN STUDENTS S ON CH.sid = S.sid
WHERE CH.cid = 'C0001'
AND CH.score > 80;

解析


7. INSERT 语句 (单条插入)

题目描述
往 STUDENTS 表中插入一条新学生信息,学号 sid = ‘S1009’,姓名 sname = ‘LinX’, email = ‘linx@school.com‘, grade = 2002。

标准答案

INSERT INTO STUDENTS (sid, sname, email, grade)
VALUES ('S1009', 'LinX', 'linx@school.com', 2002);

解析


8. INSERT 语句 (多条插入)

题目描述
在 TEACHERS 表中一次性插入两条新教师数据:

  1. tid = ‘T2001’,tname = ‘Wang Wu’,email = ‘wangwu@xxx.com‘,salary = 4500
  2. tid = ‘T2002’,tname = ‘Zhao Liu’,email = ‘zhaoliu@xxx.com‘,salary = 2000

标准答案

INSERT INTO TEACHERS (tid, tname, email, salary)
VALUES
('T2001', 'Wang Wu', 'wangwu@xxx.com', 4500),
('T2002', 'Zhao Liu', 'zhaoliu@xxx.com', 2000);

解析


9. UPDATE 语句 (单表)

题目描述
将 STUDENTS 表中学号 sid = ‘S1002’ 的学生邮箱 (email) 改为 ‘new_email@school.com‘。

标准答案

UPDATE STUDENTS
SET email = 'new_email@school.com'
WHERE sid = 'S1002';

解析


10. DELETE 语句 (单表)

题目描述
删除 TEACHERS 表中工资 (salary) 小于 2500 的所有教师记录。

标准答案

DELETE FROM TEACHERS
WHERE salary < 2500;

解析


11. 多表连接查询 (左外连接)

题目描述
查询所有 STUDENTS 表中的学生姓名以及他们在 CHOICES 表中是否有选课记录的成绩信息(score)。即使学生没有选课记录,也需要显示其姓名,score 字段可以显示为 NULL。

标准答案

SELECT S.sname, CH.score
FROM STUDENTS S
LEFT JOIN CHOICES CH ON S.sid = CH.sid;

解析


12. 多表连接查询 (内连接 + 多条件)

题目描述
查询 CHOICES 表中成绩大于 90 分并且对应的教师 salary 大于 5000 的学生姓名、课程名称、教师姓名。

标准答案

SELECT S.sname, C.cname, T.tname
FROM CHOICES CH
JOIN STUDENTS S ON CH.sid = S.sid
JOIN COURSES C ON CH.cid = C.cid
JOIN TEACHERS T ON CH.tid = T.tid
WHERE CH.score > 90
AND T.salary > 5000;

解析


13. 使用别名与表达式

题目描述
查询 TEACHERS 表中所有教师姓名 (tname) 及其工资的 12 个月总额 (命名为 AnnualSalary)。AnnualSalary = salary * 12。

标准答案

SELECT tname,
salary * 12 AS AnnualSalary
FROM TEACHERS;

解析


14. 使用聚合函数 (COUNT)

题目描述
查询 STUDENTS 表中共有多少位学生 (统计行数),并将结果命名为 StudentCount。

标准答案

SELECT COUNT(*) AS StudentCount
FROM STUDENTS;

解析


15. 使用聚合函数 (MAX、MIN、AVG)

题目描述
查询 TEACHERS 表中最大工资、最小工资以及平均工资,分别命名为 MaxSalary、MinSalary 和 AvgSalary。

标准答案

SELECT 
MAX(salary) AS MaxSalary,
MIN(salary) AS MinSalary,
AVG(salary) AS AvgSalary
FROM TEACHERS;

解析


16. GROUP BY 与 HAVING

题目描述
查询每门课程的选课人数 (COUNT(sid)),仅显示选课人数大于 3 的课程编号和对应人数。

标准答案

SELECT cid, COUNT(sid) AS StudentCount
FROM CHOICES
GROUP BY cid
HAVING COUNT(sid) > 3;

解析


17. DISTINCT 去重

题目描述
查询所有已选课 (存在于 CHOICES 表中) 的学生年级 (grade) 信息,不可重复显示。

标准答案

SELECT DISTINCT S.grade
FROM CHOICES C
JOIN STUDENTS S ON C.sid = S.sid;

解析


18. 在现有表上增加列

题目描述
在 STUDENTS 表中增加一个新列 phone,类型为 char(11),允许 NULL 值。

标准答案

ALTER TABLE STUDENTS
ADD phone CHAR(11) NULL;

解析


19. 修改列类型与名称

题目描述
将 TEACHERS 表中的 salary 列改名为 baseSalary,并将数据类型修改为 decimal(8,2)。

标准答案

EXEC sp_rename 'TEACHERS.salary', 'baseSalary', 'COLUMN';
ALTER TABLE TEACHERS
ALTER COLUMN baseSalary DECIMAL(8,2);

解析


20. 创建视图 (VIEW)

题目描述
创建一个名为 vHighScore 的视图,用于查询所有成绩大于等于 90 分的学生姓名、课程名称、成绩。

标准答案

CREATE VIEW vHighScore
AS
SELECT S.sname, C.cname, CH.score
FROM CHOICES CH
JOIN STUDENTS S ON CH.sid = S.sid
JOIN COURSES C ON CH.cid = C.cid
WHERE CH.score >= 90;

解析


21. 删除视图

题目描述
删除上一步创建的视图 vHighScore。

标准答案

DROP VIEW vHighScore;

解析


22. 创建触发器 (INSERT 或 UPDATE)

题目描述
为 TEACHERS 表创建触发器 T1,当向该表插入或更新记录时,如果 baseSalary(或 salary)低于 3000,则将其自动修改为 3000。

标准答案
下面的示例假设列名已经改为 baseSalary;如果仍是 salary,请相应调整列名。

CREATE TRIGGER T1
ON TEACHERS
FOR INSERT, UPDATE
AS
BEGIN
-- 将新插入或更新的记录里 baseSalary < 3000 的部分自动修正为 3000
UPDATE TEACHERS
SET TEACHERS.baseSalary = 3000
FROM TEACHERS
JOIN Inserted I ON TEACHERS.tid = I.tid
WHERE I.baseSalary < 3000;
END;

解析


23. 创建触发器 (DELETE)

题目描述
在 STUDENTS 表上创建触发器 T_StuDel,当删除学生记录时,需要先将此学生在 CHOICES 中的学习记录删除,然后才允许删除 STUDENTS 中对应记录。

题目提示
可以在触发器中手动先 DELETE CHOICES 表,再 DELETE STUDENTS,也可以使用其他方式保证清理。

标准答案
(一种可能实现方式——先删除 CHOICES 中相关记录,再删除 STUDENTS。)

CREATE TRIGGER T_StuDel
ON STUDENTS
INSTEAD OF DELETE
AS
BEGIN
DELETE FROM CHOICES
WHERE sid IN (SELECT sid FROM DELETED);

DELETE FROM STUDENTS
WHERE sid IN (SELECT sid FROM DELETED);
END;

解析


24. 事务处理 (简单示例)

题目描述
往 COURSES 表中插入两条记录 (cid、cname、hour)。如果任意一条插入失败,则回滚事务,保证数据一致性。

标准答案

BEGIN TRANSACTION;

BEGIN TRY
INSERT INTO COURSES (cid, cname, hour)
VALUES ('C1005', 'Physics', 60);

INSERT INTO COURSES (cid, cname, hour)
VALUES ('C1006', 'Chemistry', 55);

COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
PRINT '插入失败,事务已回滚。';
END CATCH;

解析


25. 事务处理 (多表操作)

题目描述
需要同时往 STUDENTS 表和 CHOICES 表各插入一条相关记录。如果插入 STUDENTS 表成功但插入 CHOICES 表失败,则需回滚所有操作。

标准答案

BEGIN TRANSACTION;

BEGIN TRY
-- 假设待插入学生
INSERT INTO STUDENTS (sid, sname, email, grade)
VALUES ('S1010', 'Sun Qi', 'sunqi@school.com', 2003);

-- 再往 CHOICES 表插入对应选课信息
INSERT INTO CHOICES (no, sid, tid, cid, score)
VALUES (1010, 'S1010', 'T1001', 'C0001', 85);

COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
PRINT '出现错误,事务已回滚';
END CATCH;

解析


26. CHECK 约束

题目描述
在 COURSES 表中新增一个 CHECK 约束,保证课程课时 (hour) 大于 0。

标准答案

ALTER TABLE COURSES
ADD CONSTRAINT CK_COURSES_HOUR CHECK (hour > 0);

解析


27. FOREIGN KEY 约束的创建

题目描述
尝试在 CHOICES 表上添加一个外键约束 FK_CHOICES_TEACHERS2,要求 tid 必须是 TEACHERS 表中已存在的教师编号 (tid),一旦在 TEACHERS 中删除记录时,自动删除 CHOICES 中相应的记录 (ON DELETE CASCADE)。

注意:可能与现有外键 FK_CHOICES_TEACHERS 冲突,需先删除或更改已有外键以作演示。

标准答案
(仅作示例,若已存在外键,需要先 DROP 再 CREATE。)

ALTER TABLE CHOICES
ADD CONSTRAINT FK_CHOICES_TEACHERS2
FOREIGN KEY (tid) REFERENCES TEACHERS(tid)
ON DELETE CASCADE;

解析


28. UNIQUE 约束的添加

题目描述
在 TEACHERS 表中为 email 字段添加唯一性约束,保证同一老师邮箱不重复。若 email 字段已有重复值,需要先行修改或删除。

标准答案

ALTER TABLE TEACHERS
ADD CONSTRAINT UQ_TEACHERS_EMAIL UNIQUE(email);

解析


29. 复杂多表查询 (三表连接 + 聚合)

题目描述
查询各个教师 (tid) 所授课程 (名下 CHOICES 记录) 的平均成绩,结果包含 tid、教师姓名、平均成绩(别名 AvgScore),并按 AvgScore 降序排序。

标准答案

SELECT T.tid, T.tname, AVG(CH.score) AS AvgScore
FROM TEACHERS T
JOIN CHOICES CH ON T.tid = CH.tid
GROUP BY T.tid, T.tname
ORDER BY AvgScore DESC;

解析


30. 子查询

题目描述
查询成绩高于 TEACHERS 表平均工资的学生选课记录信息 (sname、课程名称 cname、score),要求只显示满足“score > 平均 salary”的记录。

(注意:这里将教师的平均工资与学生的分数做对比仅是题目示例,并不一定具有实际业务逻辑。)

标准答案

SELECT S.sname, C.cname, CH.score
FROM CHOICES CH
JOIN STUDENTS S ON CH.sid = S.sid
JOIN COURSES C ON CH.cid = C.cid
WHERE CH.score > (
SELECT AVG(T.salary) FROM TEACHERS T
);

解析


小结

  1. 本套题目共 30 道,覆盖了 SQL Server Management Studio (SSMS) 中常见且重要的操作场景,包括数据库对象创建(表、视图、触发器)、数据操作(增删改)、查询(单表、多表、聚合、子查询)、约束(PRIMARY KEY、FOREIGN KEY、CHECK、UNIQUE)以及事务处理等关键内容。
  2. 题目设置难度适中,既包含基础语法 (简单增删改查) 又涉及多表连接、外键级联、触发器、事务等稍具复杂性或需要理解机制的考核点。
  3. 每道题目的“解析”部分对常见的使用场景、语法形式及注意事项进行了简要说明。学生在完成这些题目后,可有效复习并掌握 SQL Server 操作的核心内容。
# SQL Server