💡 课堂例题

第 6 章 · 索引、视图和触发器 · 共 5 题 · 索引/视图/触发器均基于「教学实例」库演示 · 代码可一键复制

1
为 student 表建索引
在经常查询的姓名字段上建普通索引。
sql
CREATE INDEX idx_sname ON student(Sname);
SHOW INDEX FROM student;
建完用 SHOW INDEX 能看到新索引。此后按姓名查学生会走索引,速度更快。注意它不存业务数据,只是加速结构。
2
创建并使用视图
把"学生-课程-成绩"三表连接封装成视图。
sql
CREATE VIEW v_stu_score AS
SELECT s.Sname, c.Cname, sc.score
FROM student s
JOIN sc ON s.Sno=sc.Sno
JOIN course c ON sc.Cno=c.Cno;

SELECT * FROM v_stu_score WHERE Sname LIKE '赵%';
以后查"赵姓学生成绩"直接查视图即可,不用每次重写三表 JOIN。视图本身不占数据存储,查询时实时计算。
3
BEFORE INSERT 触发器自动补班级
体会 NEW 关键字在写入前改值。
sql
DELIMITER //
CREATE TRIGGER tri_fill_class
BEFORE INSERT ON student FOR EACH ROW
BEGIN
  IF NEW.class IS NULL THEN
    SET NEW.class = '默认班';
  END IF;
END //
DELIMITER ;
插入时不填班级,触发器自动填"默认班"。这是 BEFORE 触发器"修改即将写入的数据"的典型用法。
4
BEFORE DELETE 拦截非法删除
用 SIGNAL 在删除前报错阻止。
sql
DELIMITER //
CREATE TRIGGER tri_no_del
BEFORE DELETE ON student FOR EACH ROW
BEGIN
  IF EXISTS (SELECT 1 FROM sc WHERE Sno=OLD.Sno) THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT='该生有成绩,禁止删除';
  END IF;
END //
DELIMITER ;
OLD.Sno 指向"即将被删的那一行的学号"。有成绩则 SIGNAL 抛错,删除被拦截,保护数据完整性。
5
AFTER INSERT 自动建选课记录
体会 AFTER + 操作其他表(级联)。
sql
DELIMITER //
CREATE TRIGGER tri_auto_course
AFTER INSERT ON student FOR EACH ROW
BEGIN
  INSERT INTO sc(Sno,Cno,score)
  VALUES (NEW.Sno,'01',0.0),
         (NEW.Sno,'02',0.0),
         (NEW.Sno,'03',0.0);
END //
DELIMITER ;
新生一插入,自动给他建好语数英三门 0 分记录。这是 AFTER 触发器"级联写其他表"的例子(注意操作的是 sc 不是 student 自身)。