
第1关在学生表 S 上创建删除触发器实现在表 S 中删除元组时级联删除表 SC 中该元组主键值对use 学生选课 GO --***********BEGIN********* CREATE TRIGGER trg_DeleteCascade ON S INSTEAD OF DELETE -- 使用INSTEAD OF DELETE可以捕获删除操作并在删除之前执行自定义逻辑 AS BEGIN -- 声明变量来存储被删除的学生ID DECLARE Sno INT; -- 从删除的行中获取学生ID SELECT Sno Sno FROM deleted; -- 删除SC表中对应的学生记录 DELETE FROM SC WHERE Sno Sno; -- 删除S表中的学生记录 DELETE FROM S WHERE Sno Sno; END; --***********END*********** GO第2关在选课表 SC 上创建一个触发器保证 SC 表中一次只能插人或修改一条选课元组且每门课程选修的use 学生选课 GO --***********BEGIN********* -- 检查是否已存在触发器如果存在则删除 IF EXISTS (SELECT * FROM sys.triggers WHERE object_id OBJECT_ID(N[dbo].[TR_EnforceSingleInsertOrUpdate])) DROP TRIGGER [dbo].[TR_EnforceSingleInsertOrUpdate]; GO -- 创建INSTEAD OF触发器 CREATE TRIGGER [dbo].[TR_EnforceSingleInsertOrUpdate] ON SC INSTEAD OF INSERT, UPDATE AS BEGIN SET NOCOUNT ON; -- 声明变量用于存储插入或更新的行数 DECLARE InsertOrUpdateCount INT; -- 检查是否有多个行被插入或更新 SELECT InsertOrUpdateCount COUNT(*) FROM inserted; IF InsertOrUpdateCount 1 BEGIN -- 如果有多行则输出错误信息并回滚事务 PRINT 不允许一次插入/修改多条选课元组!; ROLLBACK TRANSACTION; RETURN; END -- 检查是否为INSERT操作 IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted) BEGIN -- 检查新插入的课程人数是否超过5人 DECLARE Cno CHAR(3); SELECT Cno Cno FROM inserted; IF (SELECT COUNT(*) FROM SC WHERE Cno Cno) 5 BEGIN PRINT 超过选修该课程的人数上限!; ROLLBACK TRANSACTION; RETURN; END -- 如果通过检查则执行插入操作 INSERT INTO SC (Sno, Cno, Grade) SELECT Sno, Cno, Grade FROM inserted; END ELSE IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted) BEGIN -- 检查是否为UPDATE操作 -- 检查更新后的课程人数是否超过5人 DECLARE OldCno CHAR(3), NewCno CHAR(3); SELECT OldCno Cno FROM deleted; SELECT NewCno Cno FROM inserted; IF OldCno NewCno AND (SELECT COUNT(*) FROM SC WHERE Cno NewCno) 5 BEGIN PRINT 超过选修该课程的人数上限!; ROLLBACK TRANSACTION; RETURN; END -- 如果通过检查则执行更新操作 -- 删除旧元组 DELETE FROM SC WHERE Sno IN (SELECT Sno FROM deleted) AND Cno OldCno; -- 插入新元组 INSERT INTO SC (Sno, Cno, Grade) SELECT Sno, Cno, Grade FROM inserted; END END; --***********END*********** GO