(1)创建一个包括学生的学号及其各门功课的平均成绩的视图V_STU_AVG。
CREATE VIEW V_STU_AVG ( sNo, avgMark ) AS SELECT sNo, AVG( mark ) FROM student_course GROUP BY sNo;
查看视图中数据,理解视图的作用
SELECT * FROM V_STU_AVG;
(2)尝试对视图V_STU_AVG执行下面两条语句。
UPDATE V_STU_AVG SET avgMark = 85 WHERE sNo = '081220102';
DELETE FROM V_STU_AVG WHERE SNO = '081220102';
两条语句执行均不成功,思考错误根源。
原因:select语句包括group子句
(1)执行下列命令,配置数据环境
INSERT INTO department(dNO,dname) VALUES('060606','艺术经济学院');
INSERT INTO teacher(tNO,tName,tSex,dNO) VALUES('090901','林燕飞','女','060606');
(2)创建一个包括教师编号、教师姓名、性别和生日的060606部门所有女教师的视图。
CREATE VIEW V_TEACHER1 AS SELECT tNo,tName,tSex,tbirth FROM teacher WHERE dNo='060606' AND tSex='女' WITH CHECK OPTION;
查看视图中数据,理解视图作用
SELECT * FROM V_TEACHER1;
(3)执行下面两条语句,尝试对视图V_TEACHER1进行DML操作。
INSERT INTO V_TEACHER1 VALUES('090902','郭丽云','女','100002');
INSERT INTO V_TEACHER1 VALUES ('090903','李德刚','男','100002');
DELETE FROM V_TEACHER1 WHERE tNo='090901';
三条语句中有执行成功有执行失败的,请思考原因。
原因:第1、2句执行失败——WITH CHECK OPTION
子句来确保视图的一致性,insert:保证insert的数据能被视图查询出来,这两条语句都不满足dNo='060606' AND tSex='女'的条件。
第3句执行成功,对于delete,有无with check option都一样,但只能删除视图已有的数据。
(4)使用T-SQL语句修改视图
ALTER VIEW V_TEACHER1 AS SELECT tNo,tName,tSex,tRank,dNo FROM teacher WHERE dNo='100002' AND tSex='女';
(5)执行下面两条语句,再次尝试对视图teacher1_view进行DML操作。
INSERT INTO V_TEACHER1 VALUES('090902','郭丽云','女','讲师','100002');
INSERT INTO V_TEACHER1 VALUES('090903','李德刚','男','讲师','100002');
两条语句均可以执行成功。思考为什么第二条语句会成功?
原因:没有WITH CHECK OPTION
子句会忽略错误,所以第2句会执行成功。
(6)使用T-SQL 语句删除视图
DROP VIEW V_TEACHER1;
(1)设计一个视图,用于显示学生姓名、选修的课程名称、任课教师名称和总评成绩信息。
CREATE VIEW xuanxiu AS SELECT sName, cName, tName, Mark FROM student,course,teacher,student_course;
(2)设计一个视图,用于显示女学生信息,但是隐藏学生的身高和体重信息,只能通过视图对女生数据进行DML。
CREATE VIEW female AS SELECT sNo,sName,mNo,sBirth,sNative FROM student WHERE sSex='女' WITH CHECK OPTION;
(1)使用SQL语句为stuManage数据库的student_course表的“mark”字段创建一个非聚集索引,命名为IX_SC_MARK。
create index IX_SC_MARK ON student_course(mark);
(2)为student表的“sName”和“sSex”字段创建一个复合唯一索引,命名为IX_STUDENT_NAMESEX。
create unique index IX_STUDENT_NAMESEX ON student(sName,sSex);
(3)查看student_course表上的索引信息。
show index from student_course;
(4)使用DROP INDEX删除索引 ix_student_namesex。
drop index student.IX_STUDENT_NAMESEX;/*报错*/
drop index IX_STUDENT_NAMESEX on student;
(1)创建一个存储过程
delimiter //
create procedure list_student_department(in dept varchar(20))
begin
select sno,sname,ssex,snative,mname,dname
from student,major,department
where student.mno=major.mno and major.dno=department.dno
and dname=dept;
end;//
delimiter;
(2)执行
call list_student_department('计算机系');
(3)功能分析
创建带参的存储过程。存储工商管理系、信息管理系的学生信息,包括学号、姓名、性别、籍贯、专业、院系。
在stuManag数据库中创建一个名为show_course_Mark的存储过程,产生某门课程的选课学生的成绩情况,包括选课人数、平均成绩、及格率。要求输入某门课程的课程号,得到上述信息。
(1)创建:
delimiter //
CREATE PROCEDURE show_course_Mark(in incno CHAR(6),
out stuCount float,out avgMark FLOAT ,out ratioPass FLOAT )
BEGIN
DECLARE passCount FLOAT ;
SELECT COUNT(*) into stuCount
FROM student_course sc,course_class cc
WHERE sc.ccNo=cc.ccNo AND cc.cNo=incno;
SELECT avg(mark) into avgMark
FROM student_course sc,course_class cc
WHERE sc.ccNo=cc.ccNo AND cc.cNo=incno;
SELECT COUNT(*) into passCount
FROM student_course sc,course_class cc
WHERE sc.ccNo=cc.ccNo AND cc.cNo=incno AND mark>=60;
SET ratioPass:=passCount/stuCount;
END//
delimiter ;
(2)执行:
call show_course_Mark( '040403',@a,@b,@c);
SELECT '040403' AS '课程号', @a AS '人数', @b AS '平均分',@c AS '及格率';
1、创建一个带输入参数和输出参数的存储过程,要求实现如下功能:输入学生学号,然后输出学生的选课门数、平均分以及所选总学分。
delimiter //
CREATE PROCEDURE show_courses_Mark1(in insno CHAR(9),
out cCount float,out avgMark FLOAT ,out sumCredit FLOAT )
BEGIN
SELECT COUNT(*) into cCount
FROM student_course sc
WHERE sc.sno=insno;
SELECT avg(mark) into avgMark
FROM student_course sc
WHERE sc.sno=insno;
SELECT sum(credit) into sumCredit
FROM student_course sc,course_class cc
WHERE cc.ccNo=sc.ccNo AND sc.sno=insno ;
END//
delimiter ;
call show_courses_Mark1( '081710109',@a,@b,@c);
SELECT '081710109' AS '学号', @a AS '选课门数', @b AS '平均分',@c AS '总学分';
2、创建一个存储过程,利用输入的班级编号(学号前7位)和开课编号ccno,为全班所有同学自动选修该课程。
delimiter //
CREATE PROCEDURE insert_course1(in inclass CHAR(7),in inccno CHAR(10))
BEGIN
DECLARE stu_sno CHAR(9);
DECLARE class_sno CURSOR FOR SELECT sno FROM student WHERE substring(sno,1,7)=inclass;
open class_sno ;
REPEAT
FETCH class_sno INTO stu_sno;
INSERT INTO student_course(sno,ccno) VALUES(stu_sno,inccno);
UNTIL substring(stu_sno,1,7)!=inclass
END REPEAT;
CLOSE class_sno;
END;//
delimiter;
CALL insert_course1('0812201','2009020102');