本实验采用SQLite
数据库完成。
由于sqlite
不完全支持sql
标准,因此我采用python3
来模拟一部分函数定义和存储过程。
准备过程
单击这里下载sqlite3
的压缩包,然后解压到桌面。
像这样。
数据定义
cd 到桌面,然后运行(按要求学号后三位+db即可)代码如下:
sqlite3 108.db
教师表(JS)
复制下面的代码然后粘贴到cmd中
create table JS(
Tno varchar(7),
Tname varchar(10),
Tsex varchar(2),
Birthday datatime,
Dept varchar(20),
Sid varchar(18)
);
插入
INSERT INTO JS VALUES('T001','刘威','女','1971-3-20','电信','551021197103203121');
INSERT INTO JS VALUES('T002','张琪劲','男','1963-7-13','数理','32010119630713318X');
INSERT INTO JS VALUES('T003','李子文','女','1973-9-15','电信','551021197103203121');
INSERT INTO JS VALUES('T004','江海防','女','1960-2-18','社科','560102196002185623');
INSERT INTO JS VALUES('T005','李铁','男','1977-10-11','数理','230103197710118632');
INSERT INTO JS VALUES('T006','吴天一','男','1962-4-23','电信','320104196204237516');
INSERT INTO JS VALUES('T007','赵志华','男','1968-8-27','社科','321102196808277214');
INSERT INTO JS VALUES('T008','钱进','男','1980-7-10','电信','570102198007103452');
INSERT INTO JS VALUES('T009','孙星南','女','1981-3-2','外语','110102198103024125');
select * from JS;
课程表(Course)
复制下面的代码然后粘贴到cmd中
create table Course(
Cno varchar(10),
Cname varchar(20),
Credit integer,
property varchar(10),
Hours integer
);
插入数据:
INSERT INTO Course VALUES('01010101','大学英语1',4,'考试','');
INSERT INTO Course VALUES('01010102','普通物理1',4,'考试','');
INSERT INTO Course VALUES('01010103','高等数学1',6,'考试','');
INSERT INTO Course VALUES('01010104','形势政策',2,'考查','');
INSERT INTO Course VALUES('01010105','计算机基础',4,'考查','');
授课表
create table SK(
Tno varchar(7),
Cno varchar(10),
Hours integer
);
插入数据:
INSERT INTO SK VALUES('T001','01010105',64);
INSERT INTO SK VALUES('T002','01010102',64);
INSERT INTO SK VALUES('T009','01010101',64);
INSERT INTO SK VALUES('T004','01010104',32);
INSERT INTO SK VALUES('T005','01010103',96);
INSERT INTO SK VALUES('T006','01010105',64);
INSERT INTO SK VALUES('T003','01010101',64);
select * from SK;
修改表结构
1)在授课表中添加一个授课类别,列名为Type,类型为char(4)
ALTER TABLE SK ADD COLUMN Type char(4);
查看更改结果
select * from sqlite_master where type = "table";
2)将授课表中的Hours的类型改为Smallint
因为Sqllite不能修改字段或者删除字段,这里我直接删表重建。如果是mysql
就使用alter table news modify column Hours smallint;
drop table SK;
create table SK(
Tno varchar(7),
Cno varchar(10),
Hours Smallint
);
INSERT INTO SK VALUES('T001','01010105',64);
INSERT INTO SK VALUES('T002','01010102',64);
INSERT INTO SK VALUES('T009','01010101',64);
INSERT INTO SK VALUES('T004','01010104',32);
INSERT INTO SK VALUES('T005','01010103',96);
INSERT INTO SK VALUES('T006','01010105',64);
INSERT INTO SK VALUES('T003','01010101',64);
select * from SK;
3)删除课程表的Hours列
和上面一个道理
drop table SK;
create table SK(
Tno varchar(7),
Cno varchar(10)
);
INSERT INTO SK VALUES('T001','01010105');
INSERT INTO SK VALUES('T002','01010102');
INSERT INTO SK VALUES('T009','01010101');
INSERT INTO SK VALUES('T004','01010104');
INSERT INTO SK VALUES('T005','01010103');
INSERT INTO SK VALUES('T006','01010105');
INSERT INTO SK VALUES('T003','01010101');
select * from SK;
完成以下功能:
1) 定义表students
其中字段有:SNO CHAR(10) 、 SNAME CHAR(8) 、 AGE NUMERIC(3,0)、 SEX CHAR(2)、 BPLACE CHAR(20)、Polity CHAR(20)。要求SNO和SNAME不为空,SNO为主键。
create table students(
SNO CHAR(10) PRIMARY KEY NOT NULL,
SNAME CHAR(8) NOT NULL,
AGE NUMERIC(3,0),
SEX CHAR(2),
BPLACE CHAR(20),
Polity CHAR(20)
);
2) 在教师表JS中增加住址列
字段名为ADDR,类型为 CHAR,长度50。
ALTER TABLE JS ADD COLUMN TDDR char(50);
3) 根据students表
建立一个只包含学号、姓名、年龄的女学生表,表名为GRIL。
create table GRIL(
SNO CHAR(10) PRIMARY KEY NOT NULL,
SNAME CHAR(8) NOT NULL,
AGE NUMERIC(3,0)
);
4) 建立一成绩表
表名为score,其中字段有:SNO CHAR(10),CNO CHAR(10),scoreNUMERIC(6,0),并输入部分记录,内容自定
create table score(
SNO CHAR(10),
CNO CHAR(10),
score NUMERIC(6,0)
);
insert into students values('8101','张三','','','','');
insert into students values('8102','李四','','','','');
insert into score values('8101','01010101',60);
定义索引
在数据库中的新建一个数据表
名为js1,结构与js表相同。为js1表创建一个唯一聚集索引,索引字段为Sid,索引名为I_js_sid。
create table JS1(
Tno varchar(7),
Tname varchar(10),
Tsex varchar(2),
Birthday datatime,
Dept varchar(20),
Sid varchar(18)
);
create INDEX I_js_sid ON JS1 (Sid);
SELECT * FROM sqlite_master WHERE type = 'index';
为数据库中的course数据表
创建一个复合索引,索引名为I_cource_xf,使用Cno和Credit字段
CREATE INDEX I_cource_xf on Course(Cno, Credit);
SELECT * FROM sqlite_master WHERE type = 'index';
完成后输入.exit
退出
思考与实践
1.创建“图书借阅数据库”。
2.修改“图书借阅数据库”,相关参数自行确定。
3.在“图书借阅数据库”中创建以下四个表,并分别为这四个表写入部分数据,内容自定(提醒:各表数据之间的相关性)
创建个数据库
sqlite3 图书借阅.db
在cmd
中运行如下sql
语句
create table JS(
Jsno varchar(6),
Jname varchar(10),
Jdw varchar(20)
);
create table TS(
Tsno varchar(15),
Tname varchar(20),
Tnum smallint,
Tpos varchar(30),
Cno varchar(4)
);
create table CBS(
Cno varchar(4),
Cname varchar(20),
Ctel varchar(12),
Cyb varchar(6),
Caddr varchar(40)
);
create table JY(
Jsno varchar(6),
Tsno varchar(15),
Jydate datetime,
Hdate datetime
);
.table
插入数据
insert into JS values('000000','张三','江科大');
insert into JS values('000001','李四','江科大');
insert into JS values('000002','王五','江科大');
insert into TS values('0000000001','第一本书',10,'江苏镇江','0001');
insert into TS values('0000000002','第二本书',10,'江苏镇江','0001');
insert into TS values('0000000003','第三本书',10,'江苏镇江','0001');
insert into TS values('0000000004','第四本书',10,'江苏镇江','0001');
insert into CBS values('0001','江科大出版社','12345678910','111111','江科大');
insert into JY values('000000','0000000001','2019-11-18','2019-11-18');
创建视图
TS_view
CREATE VIEW TS_view AS select Tsno,Tname,Cname,Tnum from TS,CBS where TS.Cno=CBS.Cno;
select * from TS_view;
Jy_view
CREATE VIEW Jy_view AS
select JS.Jsno,Jname,TS.Tname,TS.Cno,Jydate,Cname,Hdate from JS,TS,CBS,JY where JS.Jsno = JY.Jsno and TS.Tsno=JY.Tsno;
select * from Jy_view;
建立索引
随便建建
create INDEX ts_index ON TS(Tsno);
create INDEX jy_index ON JY(Jsno);
create INDEX cbs_index ON CBS(Cno);
create INDEX js_index ON JS(Jsno);
完整性约束
删表重建吧。
懒得写了。草
数据操纵
1. 在查询分析器中,对“教师授课管理数据库”表中数据进行下列查询操作
(1)查询所有男学生的姓名、出生日期。
select SNAME,BPLACE from students where SEX='男';
(2)查询男女教师的人数。
select Tsex,count(Tno) from JS group by Tsex;
(3)找出年龄在20~23岁之间的学生的学号、姓名和年龄,并按年龄升序排序。
select * from students where AGE>=20 and AGE<=23;
(4)找出年龄超过平均年龄的学生姓名。
select SNAME from students where AGE>(select avg(AGE) from students);
(5)查询成绩不及格的学生信息,包括姓名、学号、课程名和成绩。
select SNAME,Students.SNO,Course.Cname,score.score
from students,Course,score
where score.score<60 and students.SNO=score.sno and score.Cno=Course.Cno;
(6)查询所有讲授“01010105”课程的教师信息。
SELECT JS.Tno,Tname,Tsex,Birthday,Dept,Sid from JS,SK where JS.Tno=SK.Tno and SK.Cno='01010105';
(7)查询1971年以前(含1971年)出生的所有教师的任课信息,包括教师姓名、出生日期、所授课程名、学时数。
select Tname,Birthday,Course.Cname,Course.Hours
from JS,Course,SK
where JS.Birthday<'1972-1-1' and JS.Tno=SK.Tno and Course.Cno=SK.Cno;
(8)查询所有未授课的教师信息。
select * from JS where JS.Tno not in (select JS.Tno from JS,SK where JS.Tno = SK.Tno);
2.在查询分析器中,对表中数据进行插入操作
(1)向students表中插入几条记录,内容自定。
insert into students values('8089','张八','女','','','');
(2)把教师李映雪(教师号为1476,其他内容自定)的记录加入到教师表JS中。
insert into JS values('T010','李映雪','女','1971-3-20','电信','551021197103203181','');
(3)根据students表,建立一个只包含学号、姓名、年龄的女学生表,表名为GRIL。
建过了
3.在查询分析器中,对表中数据进行修改操作
(1)把所有学生的年龄增加一岁。
update students set AGE=AGE+1;
(2)将所有选修某一指定课程的学生成绩增加5分。
update score set score=score+5 where Cno='01010101';
(3)将某个学生的所有成绩置0。
update score set score = 0 where Sno='8102';
4.在查询分析器中,对表中数据进行删除操作
(1)从教师表JS中删除年龄已到60岁的退休教师的数据。
drop from JS where datetime(CURRENT_TIMESTAMP,'localtime')-Birthday>59;
(2)将学生表student中的某个学生删除,并删除其他表中与该学生相关的信息。
一个一个删吧。如果用外键的话,直接
drop from student where SNO=?
FOREIGN KEY 学生信息ID
REFERENCES 学生信息 (学生信息ID)
ON DELETE CASCADE
数据库编程
T-SQL的流程控制语句、游标的使用编写程序完成以下功能,在查询分析器中执行程序,并记录结果。
T-SQL的流程控制语句、游标的使用
1.
在score表中求某班学生某门课程的最高分和最低分的学生信息,包括学号、姓名、课程名、成绩四个字段。
最高分:
SELECT students.SNO,students.SNAME,Course.Cname,score
FROM score,students,Course
where students.SNO=score.SNO and Course.Cno=score.Cno
ORDER BY score DESC
limit 1;
最低分:
SELECT students.SNO,students.SNAME,Course.Cname,score
FROM score,students,Course
where students.SNO=score.SNO and Course.Cno=score.Cno
ORDER BY score ASC limit 1;
2.
查询某班的学生信息,要求列出的字段为:班级、本班内的学号、姓名、性别、出生日期、政治面貌
增加一个班级表 banji 和一个班级学生关系表:
create table banji(
Bno varchar(4),
Bname varchar(20)
);
create table banji_student(
Sno char(10),
Bno varchar(4)
);
向表内添加数据:
insert into students values('8103','张五',18,'男','1999-08-07','团员');
insert into students values('8104','李五',18,'女','1998-09-04','党员');
insert into banji values('100','一班');
insert into banji_student values('8103','100');
insert into banji_student values('8104','100');
查询一班的学生信息:
select banji.Bname, students.SNO,students.SNAME,students.SEX,students.BPLACE,students.Polity
from banji,banji_student,students
where banji.Bno = 100 and banji_student.Sno = students.SNO
3.
在student表中先插入三条新记录,其中的Pollity字段的值为NULL,要求对记录进行查询时,对应的NULL值在显示时显示为“群众”
drop table students;
create table students(
SNO CHAR(10) PRIMARY KEY NOT NULL,
SNAME CHAR(8) NOT NULL,
AGE NUMERIC(3,0),
SEX CHAR(2),
BPLACE CHAR(20),
Polity CHAR(20) DEFAULT '群众'
);
insert into students values('8103','张五',18,'男','1999-08-07','团员');
insert into students values('8104','李五',18,'女','1998-09-04','党员');
insert into students values('8101','张三','','','','');
insert into students values('8102','李四','','','','');
select * from students;
insert into students(SNO,SNAME,AGE,SEX,BPLACE) values('8105','王八',18,'男','1999-08-08');
4.
根据score表中考试成绩,查询某班学生某门课程的平均成绩,并根据平均成绩输出相应的提示信息
向score表中添加数据
insert into score values('8102','01010101',50);
SELECT avg(score),Course.Cname,banji.Bname
FROM score,students,Course,banji,banji_student
where Course.Cno=score.CNO and banji.Bno=banji_student.Bno
and banji.Bno=100 and banji_student.Sno = students.SNO and banji_student.Sno=score.SNO;
5.
根据score表中考试成绩,查询某班学生的考试情况,并使用CASE将课程号替换为课程名称
SELECT score,(case score.CNO when 1 then Course.Cname ELSE Course.Cname END),banji.Bname
FROM score,students,Course,banji,banji_student
where Course.Cno=score.CNO and banji.Bno=banji_student.Bno
and banji.Bno=100 and banji_student.Sno = students.SNO and banji_student.Sno=score.SNO;
6.
根据score表中考试成绩,查询某班学生的考试情况,并根据考试分数输出考试等级。
SELECT students.SNAME,(case when score >=60 then '及格' else '不及格' end),Course.Cname,banji.Bname
FROM score,students,Course,banji,banji_student
where Course.Cno=score.CNO and banji.Bno=banji_student.Bno
and banji.Bno=100 and banji_student.Sno = students.SNO and banji_student.Sno=score.SNO;
存储过程的创建与调用
因为sqlite
功能有限。这里选择python
来模拟逻辑。
1.
创建一个存储过程stuscoreinfo,完成的功能是在表student、表course和表score中查询以下字段:班级、学号、姓名、性别、课程名称、考试分数。
先修改一下张三的性别
update students set SEX='女' where SNAME='张三';
编写sql
语句
select banji.Bname,students.SNAME,students.SEX,Course.Cname,score.score
from banji,banji_student,students,Course,score
where banji.Bno=banji_student.Bno and banji_student.Sno=students.SNO and score.Cno=Course.Cno and score.Sno=students.SNO;
使用python
进行封装调用。
python
代码如下:
import sqlite3
def stuscoreinfo():
conn = sqlite3.connect('108.db')
cursor = conn.cursor()
cursor.execute("select banji.Bname,students.SNAME,students.SEX,Course.Cname,score.score from banji,banji_student,students,Course,score where banji.Bno=banji_student.Bno and banji_student.Sno=students.SNO and score.Cno=Course.Cno and score.Sno=students.SNO;")
values = cursor.fetchall()
print (values)
cursor.close()
conn.close()
stuscoreinfo()
2.
创建一个带有参数的存储过程stu_info,该存储过程根据传入的学生编号,在student中查询此学生的信息。
编写sql如下所示
select * from students where SNO='8101'
python
封装如下
import sqlite3
def stu_info(num):
conn = sqlite3.connect('108.db')
cursor = conn.cursor()
cursor.execute("select * from students where SNO='"+str(num)+"'")
values = cursor.fetchall()
print (values)
cursor.close()
#conn.commit()
conn.close()
stu_info(8101)
3.
创建一个带有参数的存储过程stu_age,该存储过程根据传入的学生编号,在student中计算此学生的年龄,并根据程序执行结果返回不同的值,程序执行成功,返回整数0,如果执行错误,则返回错误号。
import sqlite3
import time
def stu_age():
try:
conn = sqlite3.connect('108.db')
cursor = conn.cursor()
cursor.execute("select BPLACE,SNAME from students");
values = cursor.fetchall()
for i in values:
if i[0].split('-')[0]!='':
print (str(int(time.localtime(time.time())[0])-int(i[0].split('-')[0]))+'|'+str(i[1]))
else:
print ('未填写' + '|'+str(i[1]))
cursor.close()
conn.close()
return 0
except BaseException:
return 1
stu_age()
4-8
上面均已经python模拟了存储过程的逻辑。
自定义函数的创建与调用
1.
使用自定义函数fun_sumscores。求score表中各班级的各门课程的平均分。主程序调用该函数,显示各班级、各课程的平均分。
这是修改sql
之前的信息
编写sql
语句如下:
select banji.Bname,avg(score),Course.Cname
from banji,score,banji_student,Course
where banji.Bno=banji_student.Bno and banji_student.Sno=score.Sno and Course.Cno=score.Cno
group by Course.Cname;
python
封装如下
import sqlite3
def fun_sumscores():
try:
conn = sqlite3.connect('108.db')
cursor = conn.cursor()
cursor.execute("select banji.Bname,avg(score),Course.Cname from banji,score,banji_student,Course where banji.Bno=banji_student.Bno and banji_student.Sno=score.Sno and Course.Cno=score.Cno group by Course.Cname;");
values = cursor.fetchall()
print (values)
cursor.close()
conn.close()
return 0
except BaseException:
return 1
fun_sumscores()
2.
编写一个用户自定义函数fun_sumscores。要求根据输入的班级号和课程号,求得此班此门课程的总分。主程序调用该函数,查询指定班级的某课程的总分。
编写sql
如下
select Cname,sum(score)
from score,banji,banji_student,Course
where banji.Bno=100 and score.Cno='01010101' and Course.Cno=score.Cno and banji.Bno=banji_student.Bno and banji_student.Sno=score.SNO;
python
封装如下
import sqlite3
def fun_sumscores(Bno,Cno):
try:
conn = sqlite3.connect('108.db')
cursor = conn.cursor()
cursor.execute("select Cname,sum(score) from score,banji,banji_student,Course where banji.Bno="+Bno+" and score.Cno='"+Cno+"' and Course.Cno=score.Cno and banji.Bno=banji_student.Bno and banji_student.Sno=score.SNO;");
values = cursor.fetchall()
print (values)
cursor.close()
conn.close()
return 0
except BaseException:
return 1
fun_sumscores('100','01010101')
3.
编写一自定义函数,用于查询给定姓名的学生,如果没找到,返回0,否则返回满足条件的学生人数。主程序调用该函数,查询“李浩”的学生,并根据函数的返回值进行输出。
编写sql
如下
select count(*) from students where SNAME='张三';
python
模拟如下
import sqlite3
def fun_select(name):
try:
conn = sqlite3.connect('108.db')
cursor = conn.cursor()
cursor.execute("select count(*) from students where SNAME='"+name+"'")
values = cursor.fetchall()
print (values)
cursor.close()
conn.close()
return 0
except BaseException:
return 1
fun_select('张三')
思考与实践
对“图书借阅数据库”中的JS、TS、CBS、JY表进行操作:
查询各借书人的借阅量(若重复借阅一本书,则以一本书计),要求得到:借书证号、姓名、借书量。
编写sql
select JS.Jsno,JS.Jname,count(JY.Jsno)
from JS,JY
where JS.Jsno=JY.Jsno
Group by JS.Jsno;