godoforange

本实验采用SQLite数据库完成。
由于sqlite不完全支持sql标准,因此我采用python3来模拟一部分函数定义和存储过程。

准备过程

单击这里下载sqlite3的压缩包,然后解压到桌面。
像这样。

然后使用win+R 运行cmd shell

数据定义

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;

懒得填数据了,把20改成18就能查出来了

(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;

运行效果如下

分类:

技术点:

相关文章:

  • 2021-07-23
  • 2021-07-19
  • 2021-11-20
  • 2021-07-03
猜你喜欢
  • 2021-12-19
  • 2021-04-13
  • 2022-01-02
  • 2021-07-19
相关资源
相似解决方案