数据库概论实验(黑龙江大学)
第一部分:SQL语言实践
(一)实验目的
1、了解某个关系数据库管理系统(例如:MySQL、SQL Server、Oracle等)的基本操作。
2、熟练掌握SQL数据定义语句,能够熟练使用SQL数据定义语句创建、修改及删除关系模式。
3、熟练掌握SQL数据操纵语句,能够熟练使用SQL数据操纵语句插入、修改及删除元组。
4、熟练掌握SQL数据查询语句,能够熟练使用SQL数据查询语句实现数据基本查询,包括单表查询、统计查询、连接查询及嵌套查询等。
(二)实验内容
1、创建关系模式
(1)职工表employee,其结构为(职工号ssn char(18),职工名name char(10),生日bdate char(10),地址address char(30),性别sex char(2),薪水salary float,直接领导人职工号superssn char(18) ,部门号dno char(3)),其中职工号为主码,其它属性值要求非空。
(2)部门表department,其结构为(部门号dnumber char(3),部门名dname varchar(30),部门经理职工号mgrssn char(18),部门经理受雇日期mgrstartdate date),其中部门号为主码,其它属性值要求非空。
(3)部门地址表depart_location,其结构为(部门号dnumber char(3),部门地址dlocation varchar(30)),其中部门号为主码,其它属性值要求非空。
(4)项目表project,其结构为(项目号pnumber char(3),项目名pname varchar(30),项目所在地plocation varchar(30),项目隶属部门号dnum char(3)),其中项目号为主码,其它属性值要求非空。
(5)职工参与项目表works_on,其结构为(职工号essn char(18),项目号pno char(3),工作时间hours int),其中(职工号,项目号)为主码,其它属性值要求非空。
(6)家属表dependent,其结构为(职工号essn char(18),家属名dependent_name char(10),性别sex char(2),生日bdate char(10),与职工关系relationship char(10)),其中(职工号,家属名)为主码,其它属性值要求非空。
2、为上述关系模式分别插入如下数据:
(1)职工表:employee
| ssn | name | bdate | address | sex | salary | superssn | dno |
| 230101198009081234 | 张三 | 1980-09-08 | 哈尔滨道里区十二道街 | 男 | 3125 | 23010119751201312X | d1 |
| 230101198107023736 | 李四 | 1981-07-02 | 哈尔滨道外区三道街 | 男 | 2980 | 23010119751201312X | d1 |
| 23010119751201312X | 张红 | 1975-12-01 | 哈尔滨南岗区三十道街 | 男 | 4260 | 23010119751201312X | d1 |
| 230101198204078121 | 王二 | 1982-04-07 | 哈尔滨动力区六十道街 | 男 | 2890 | 23010119751201312X | d1 |
| 23010119950101XXXX | 灰太狼 | 1995-01-01 | 青青草原狼堡 | 男 | 1200 | 23010119960101XXXX | d2 |
| 23010119960101XXXX | 红太狼 | 1996-01-01 | 青青草原狼堡 | 女 | 3600 | 23010119960101XXXX | d2 |
| 23010120050101XXXX | 喜羊羊 | 2005-01-01 | 青青草原大肥羊学校 | 男 | 1000 | 23010120050101XXXX | d3 |
| XXXXXXXXXXXXXXXXXX | 超人 | 3000-01-01 | 外星 | 男 | 100000 | 23010120050101XXXX | d4 |
(2)部门表:department
| dnumber | dname | mgrssn | mgrstartdate |
| d1 | 研发部 | 23010119751201312X | 2008-01-01 |
| d2 | 捕羊部 | 23010119960101XXXX | 2006-01-01 |
| d3 | 防狼部 | 23010120050101XXXX | 2006-01-01 |
| d4 | 全能部 | XXXXXXXXXXXXXXXXXX | 3000-01-01 |
(3)部门地址表depart_location
| dnumber | dlocation |
| d1 | 哈尔滨 |
| d2 | 青青草原 |
| d3 | 青青草原 |
| d4 | 地球 |
(4)项目表:project
| pname | pnumber | plocation | dnum |
| 研究项目1 | p1 | 哈尔滨 | d1 |
| 哈同公路 | p2 | 哈尔滨 | d1 |
| 立交桥 | p3 | 哈尔滨 | d1 |
| 机场建设 | p4 | 哈尔滨 | d1 |
| 抓羊 | p5 | 青青草原 | d2 |
| 吃羊 | p6 | 青青草原 | d2 |
| 防狼 | p7 | 青青草原 | d3 |
(5)员工参与项目表:works_on
| essn | pno | hours |
| 23010119751201312X | p1 | 100 |
| 23010119751201312X | p2 | 90 |
| 23010119751201312X | p3 | 85 |
| 23010119751201312X | p4 | 100 |
| 230101198009081234 | p1 | 65 |
| 230101198009081234 | p2 | 76 |
| 230101198009081234 | p3 | 67 |
| 230101198107023736 | p2 | 89 |
| 230101198107023736 | p3 | 79 |
| 230101198107023736 | p4 | 91 |
| 230101198204078121 | p2 | 23 |
| 230101198204078121 | p3 | 36 |
| 23010119950101XXXX | p2 | 11 |
| 23010119950101XXXX | p5 | 100 |
| 23010119950101XXXX | p6 | 100 |
| 23010119960101XXXX | p5 | 100 |
| 23010119960101XXXX | p6 | 100 |
| 23010120050101XXXX | p7 | 100 |
| XXXXXXXXXXXXXXXXXX | p1 | 100 |
| XXXXXXXXXXXXXXXXXX | p2 | 100 |
| XXXXXXXXXXXXXXXXXX | p3 | 100 |
| XXXXXXXXXXXXXXXXXX | p4 | 100 |
| XXXXXXXXXXXXXXXXXX | p5 | 100 |
| XXXXXXXXXXXXXXXXXX | p6 | 100 |
| XXXXXXXXXXXXXXXXXX | p7 | 100 |
(6)家属表:dependent
| essn | dependent_name | sex | bdate | relationship |
| 230101198009081234 | 张三妻 | 女 | 1983-09-02 | 配偶 |
| 230101198009081234 | 张三儿 | 男 | 2005-01-01 | 父子 |
| 23010119950101XXXX | 小灰灰 | 男 | 2009-01-01 | 父子 |
| 23010119960101XXXX | 小灰灰 | 男 | 2009-01-01 | 母子 |
3、完成下列查询
(1)查询参加了“p2”项目的职工号。
(2)查询参加了项目名为“哈同公路”的职工数量。
(3)查询在“研发部”工作且工资低于3000元的职工名字和地址。
(4)查询没有参加项目“p1”的职工姓名。
(5)查询没有家属的职工名字。
(6)查询由“张红”领导的职工的姓名和所在部门的名字。
(7)查询至少参加了3个项目的职工号。
(8)查询至少参加了项目“p1”和项目“p2”的职工号。
(9)查询参加了全部项目的职工号和姓名。
(10)在参加了“p2”项目的职工中,查询比职工“张三”的酬金低的职工姓名 。
(11)查询这样的职工姓名,该职工参加了“张三”没有参加的某个项目。
(12)查询这样的职工姓名,该职工至少参加了王二参加的所有项目(不列出王二)。
(13)查询这样的职工姓名和他在项目中的平均工作时间,该职工至少参加了两
个项目,并且在这两个项目中的工作时间都不低于100小时。
(14)查询这样的职工姓名,该职工至少参加了三个部门的项目。
(15)查询至少参加了项目“P1”、项目“P2”和项目“P3”的职工姓名。
4、关系模式及数据的维护
(1)为dependent表添加工作单位和职业两个属性。
(2)为工作单位和职业这两个属性添加值。
(3)把employee表中所有职工的工资改为3000元。
(4)把dependent表中“230101198009081234”的家属张三妻的职业改为“教师”。
(5)把研究部的职工工资提高10%。
(6)删除dependent表中职工“23010119950101XXXX”的家属。
(7)删除在研究部工作的职工信息。
(8)分别删除工作单位和职业属性。
(三)实验代码
#题目1 源代码:
create table employee (ssn char ( 18 ) primary key,name char ( 10 ) not null,bdate char ( 10 ) not null,address char ( 30 ) not null,sex char ( 2 ) not null,salary float not null,superssn char ( 18 ) not null,dno char ( 3 ) not null
);create table department (dnumber char ( 3 ) primary key,dname varchar ( 30 ) not null,mgrssn char ( 18 ) not null,mgrstartdate date not null
);create table depart_location (dnumber char ( 3 ) primary key,dlocation varchar ( 30 ) not null
);create table project (pnumber char ( 3 ) primary key,pname varchar ( 30 ) not null,plocation varchar ( 30 ) not null,dnum char ( 30 ) not null
);create table works_on (essn char ( 18 ) not null,pno char ( 3 ) not null,hours int not null,primary key ( essn, pno )
);create table dependent (essn char ( 18 ) not null,dependent_name char ( 10 ) not null,sex char ( 2 ) not null,bdate char ( 10 ) not null,relationship char ( 10 ) not null,primary key ( essn, dependent_name )
);#题目2 源代码:
insert into employee
values( '230101198009081234', '张三', '1980-09-08', '哈尔滨道里区十二道街', '男', 3125, '23010119751201312X', 'd1' ),( '230101198107023736', '李四', '1981-07-02', '哈尔滨道外区三道街', '男', 2980, '23010119751201312X', 'd1' ),( '23010119751201312X', '张红', '1975-12-01', '哈尔滨南岗区三十道街', '男', 4260, '23010119751201312X', 'd1' ),( '230101198204078121', '王二', '1982-04-07', '哈尔滨动力区六十道街', '男', 2890, '23010119751201312X', 'd1' ),( '23010119950101XXXX', '灰太狼', '1995-01-01', '青青草原狼堡', '男', 1200, '23010119960101XXXX', 'd2' ),( '23010119960101XXXX', '红太狼', '1996-01-01', '青青草原狼堡', '女', 3600, '23010119960101XXXX', 'd2' ),( '23010120050101XXXX', '喜羊羊', '2005-01-01', '青青草原大肥羊学校', '男', 1000, '23010120050101XXXX', 'd3' ),( 'XXXXXXXXXXXXXXXXXX', '超人', '3000-01-01', '外星', '男', 100000, '23010120050101XXXX', 'd4' );insert into department
values( 'd1', '研发部', '23010119751201312X', '2008-01-01' ),( 'd2', '捕羊部', '23010119960101XXXX', '2006-01-01' ),( 'd3', '防狼部', '23010120050101XXXX', '2006-01-01' ),( 'd4', '全能部', 'XXXXXXXXXXXXXXXXXX', '3000-01-01' );insert into depart_location
values( 'd1', '哈尔滨' ),( 'd2', '青青草原' ),( 'd3', '青青草原' ),( 'd4', '地球' );insert into project
values( 'p1', '研究项目1', '哈尔滨', 'd1' ),( 'p2', '哈同公路', '哈尔滨', 'd1' ),( 'p3', '立交桥', '哈尔滨', 'd1' ),( 'p4', '机场建设', '哈尔滨', 'd1' ),( 'p5', '抓羊', '青青草原', 'd2' ),( 'p6', '吃羊', '青青草原', 'd2' ),( 'p7', '防狼', '青青草原', 'd3' );insert into works_on
values( '23010119751201312X', 'p1', 100 ),( '23010119751201312X', 'p2', 90 ),( '23010119751201312X', 'p3', 85 ),( '23010119751201312X', 'p4', 100 ),( '230101198009081234', 'p1', 65 ),( '230101198009081234', 'p2', 76 ),( '230101198009081234', 'p3', 67 ),( '230101198107023736', 'p2', 89 ),( '230101198107023736', 'p3', 79 ),( '230101198107023736', 'p4', 91 ),( '230101198204078121', 'p2', 23 ),( '230101198204078121', 'p3', 36 ),( '23010119950101XXXX', 'p2', 11 ),( '23010119950101XXXX', 'p5', 100 ),( '23010119950101XXXX', 'p6', 100 ),( '23010119960101XXXX', 'p5', 100 ),( '23010119960101XXXX', 'p6', 100 ),( '23010120050101XXXX', 'p7', 100 ),( 'XXXXXXXXXXXXXXXXXX', 'p1', 100 ),( 'XXXXXXXXXXXXXXXXXX', 'p2', 100 ),( 'XXXXXXXXXXXXXXXXXX', 'p3', 100 ),( 'XXXXXXXXXXXXXXXXXX', 'p4', 100 ),( 'XXXXXXXXXXXXXXXXXX', 'p5', 100 ),( 'XXXXXXXXXXXXXXXXXX', 'p6', 100 ),( 'XXXXXXXXXXXXXXXXXX', 'p7', 100 );insert into dependent
values( '230101198009081234', '张三妻', '女', '1983-09-02', '配偶' ),( '230101198009081234', '张三儿', '男', '2005-01-01', '父子' ),( '23010119950101XXXX', '小灰灰', '男', '2009-01-01', '父子' ),( '23010119960101XXXX', '小灰灰', '男', '2009-01-01', '母子' );#题目3 源代码:--(1)查询参加了“p2”项目的职工号。
select essn
from works_on
where pno = 'p2';--(2)查询参加了项目名为“哈同公路”的职工数量。
select count(*)
from works_on
where pno = ( select pnumber from project where pname = '哈同公路' );--(3)查询在“研发部”工作且工资低于3000元的职工名字和地址。
select name, address
from employee
where salary < 3000 anddno = ( select dnumber from department where dname = '研发部' ) ;--(4)查询没有参加项目“p1”的职工姓名。
select name
from employee
where ssn not in ( select essn from works_on where pno = 'p1' );--(5)查询没有家属的职工名字。
select name
from employee
where ssn not in ( select essn from dependent );--(6)查询由“张红”领导的职工的姓名和所在部门的名字。
select name, dname
from employee, department
where dno = dnumber andsuperssn = (select ssn from employee where name = '张红');--(7)查询至少参加了3个项目的职工号。
select essn
from works_on
group by essn
having count(*) >= 3;--(8)查询至少参加了项目“p1”和项目“p2”的职工号。
SELECT DISTINCT w1.essn
from works_on w1, works_on w2
where w1.pno = 'p1' and w2.pno = 'p2';--(9)查询参加了全部项目的职工号和姓名。
select ssn, name
from employee
where not exists (select *from projectwhere not exists ( select * from works_on where pno = pnumber and essn = ssn ));--(10)在参加了“p2”项目的职工中,查询比职工“张三”的酬金低的职工姓名 。
select name
from employee
where ssn in ( SELECT essn FROM works_on WHERE pno = 'p2' )and salary < ( SELECT salary FROM employee WHERE name = "张三" );--(11)查询这样的职工姓名,该职工参加了“张三”没有参加的某个项目。
select distinct name
from employee, works_on
where ssn = essn andpno not in ( select pno from works_on, employee where essn = ssn and name = "张三" );--(12)查询这样的职工姓名,该职工至少参加了王二参加的所有项目(不列出王二)。
select name
from employee
where name != '王二' and not exists (select *from works_on w1where essn = (select ssn from employee where name = '王二') andnot exists ( select * from works_on w2 where w1.pno = w2.pno AND essn = ssn ));--(13)查询这样的职工姓名和他在项目中的平均工作时间,该职工至少参加了两个项目,并且在这两个项目中的工作时间都不低于100小时。
select name, avg( hours )
from employee, works_on
where ssn = essn and essn in (select w1.essnfrom works_on w1, works_on w2where w1.essn = w2.essnand w1.pno != w2.pnoand w1.hours >= 100and w2.hours >= 100 )
group by name;--(14)查询这样的职工姓名,该职工至少参加了三个部门的项目。
select name
from employee
where ssn in (select essnfrom works_on, projectwhere pno = pnumbergroup by essnhaving count( distinct dnum ) >= 3);--(15)查询至少参加了项目“P1”、项目“P2”和项目“P3”的职工姓名。
select name
from employee
where ssn in (select w1.essnfrom works_on w1join works_on w2 on ( w1.pno = 'p1' and w2.pno = 'p2' and w1.essn = w2.essn)join works_on w3 on ( w3.pno = 'p3' and w1.essn = w3.essn));#题目4 源代码:
--(1)为dependent表添加工作单位和职业两个属性。
alter table dependent add workunit char ( 30 );
alter table dependent add profession char ( 10 );--(2)为工作单位和职业这两个属性添加值。
update dependent set workunit = '黑龙江大学';
update dependent set profession = "教师";--(3)把employee表中所有职工的工资改为3000元。
update employee SET salary = 3000;--(4)把dependent表中“230101198009081234”的家属张三妻的职业改为“教师”。
update dependent
set profession = "教师"
where essn = "230101198009081234" and dependent_name = '张三妻';--(5)把研究部的职工工资提高10%。
update employee
set salary = salary * 1.1
where dno = ( select dnumber from department where dname = '研发部' );--(6)删除dependent表中职工“23010119950101XXXX”的家属。
delete
from dependent
where essn = '23010119950101XXXX';--(7)删除在研究部工作的职工信息。
delete
from employee
where dno = ( select dnumber from department where dname = '研发部' );--(8)分别删除工作单位和职业属性。
alter table dependent drop workunit;
alter table dependent drop profession;-----------------------------------------------------------------------------
# (职工号,职工名,生日,地址,性别,薪水,直接领导人职工号,部门号)
#职工表:employee(ssn, `name`, bdate, address, sex, salary, superssn, dno)# (部门号,部门名,部门经理职工号,部门经理受雇日期)
#部门表:department(dnumber, dname, mgrssn, mgrstartdate)# (部门号,部门地址)
#部门地址表depart_location(dnumber, dlocation)# (项目号,项目名,项目所在地,项目隶属部门号)
#项目表:project(pname, pnumber, plocation, dnum)# (职工号,项目号,工作时间)
#员工参与项目表:works_on (essn, pno, hours)# (职工号,家属名,性别,生日,与职工关系)
#家属表:dependent(essn, dependent_name, sex, bdate, relationship)
------------------------------------------------------------------------------
第二部分:PL/SQL语言实践
(一)实验目的
1、熟练掌握存储过程的设计和使用方法,能够熟练使用PL/SQL语句定义存储过程。
2、熟练掌握触发器的设计和使用方法,能够熟练使用PL/SQL语句定义触发器。
(二)实验内容
1、给定部门号(键盘输入),输出该部门每个员工的基本信息及参与项目信息。
2、显示最高工资的职工所在的部门名称和工资,并输出该部门中职工的信息。
3、在表department上创建一个触发器deaprt_update,当更改部门号时同步更改employee表中对应的部门号。
4、在表employee上创建一个触发器employee_delete,当删除职工元组同步删除对应职工的参与项目元组。
5、验证以上两个触发器。
(三)实验代码
#题目1 源代码:
--(1)给定部门号(键盘输入),输出该部门每个员工的基本信息及参与项目信息。
delimiter $
create definer=`root`@`localhost` procedure `selectDno`(in `inputDno` char(3))
beginselect *from employee e, works_on wwhere e.dno = inputDno and e.ssn = w.essn;
end$
delimiter ;
# 调用
set @inputDno = 'd1';
call selectDno(@inputDno);--(2)显示最高工资的职工所在的部门名称和工资,并输出该部门中职工的信息。
delimiter $
create definer=`root`@`localhost` procedure `showAll`()
beginselect d.dname,e1.*from employee e1, department dwhere e1.salary = (select MAX(salary) from employee) and e1.dno = d.dnumber;
end$
delimiter ;
# 调用
call showAll();--(3)在表department上创建一个触发器depart_update,当更改部门号时同步更改employee表中对应的部门号。
delimiter $
create definer=`root`@`localhost` trigger `depart_update` after update on `department` for each row
beginupdate employeeset dno = new.dnumberwhere dno = old.dnumber;
end$
delimiter ;
# 测试
update department
set dnumber = 'd5'
where dnumber = 'd4';--(4)在表employee上创建一个触发器employee_delete,当删除职工元组同步删除对应职工的参与项目元组。
delimiter $
create definer=`root`@`localhost` trigger `employee_delete` after delete on `employee` for each rowbegindeletefrom works_onwhere essn = old.ssn;end$delimiter ;# 测试deletefrom employeewhere ssn = '23010119751201312X';------------------------------------------------------------------------------# (职工号,职工名,生日,地址,性别,薪水,直接领导人职工号,部门号)#职工表:employee(ssn, `name`, bdate, address, sex, salary, superssn, dno)# (部门号,部门名,部门经理职工号,部门经理受雇日期)#部门表:department(dnumber, dname, mgrssn, mgrstartdate)# (部门号,部门地址)#部门地址表depart_location(dnumber, dlocation)# (项目号,项目名,项目所在地,项目隶属部门号)#项目表:project(pname, pnumber, plocation, dnum)# (职工号,项目号,工作时间)#员工参与项目表:works_on (essn, pno, hours)# (职工号,家属名,性别,生日,与职工关系)#家属表:dependent(essn, dependent_name, sex, bdate, relationship)----------------------------------------------------------------------------------
第三部分:创建数据库及数据操作功能实践
(一)实验目的
熟练掌握数据库管理系统中创建数据库、关系模式维护以及数据维护操作的实现技术。
(二) 实验内容
注:以下所有功能的实现,要进行语法和语义检查,并注意维护相应的数据
字典文件。
1、用高级语言建立数据库表。
(1)设计文件存储结构和存取方法。
(2)属性的个数任意,属性的类型至少包括整数和字符串。
(3)把表的相关信息存入数据字典。
- 用高级语言为关系表插入元组。
(1)用VALUES子句为新建立的关系插入元组。
(2)用VALUES子句在关系模式修改之后按照新的模式插入元组。(选做)
3、用高级语言实现属性的添加和删除功能。(选做)
(1)为关系表添加属性并维护数据字典。
(2)为关系表删除属性并维护数据字典。
4、用高级语言实现表中元组的删除和修改功能。
(1)实现删除关系表元组的功能,包括如下两种情况:
a) 没有WHERE条件,删除关系中的所有元组。
b) 指定WHERE条件,删除满足条件的元组。
(2)实现修改关系表元组的功能,包括如下两种情况(选做):
a) 没有WHERE条件,修改所有元组的指定属性的值。
b) 指定WHERE条件,修改满足条件的元组的指定属性的值。
5、用高级语言实现表的删除功能。
(1)删除表并维护数据字典。
6、用高级语言实现显示数据库表的功能,用于对上面的操作结果进行测试。
(1)实现“SELECT * FROM 表名”。
(2)显示表的结构和内容。
(三) 实验代码

注意:创建一个空的table.txt 和src同级别
package cl.lh.sy3;import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Sy3 {// 注意:table.txt 必须在项目名(DataBase)下, 和src在同一级别// table.txt内容可以删, 但文件本身不要删,, 其他表名文件可以删// 然后每创建一个表, 表名会存在table.txt里面, 然后在table.txt附件会生成一个和表名一样的文件// create table works ( essn char , pno char , hours int );// insert into works values ( 23010119751201312X , p1 , 100 );// insert into works values ( 23010119100000002X , p1 , 111 );// insert into works values ( 23010119111100002X , p2 , 151 );// insert into works values ( 288888888882010000 , p2 , 200 );// insert into works values ( 230199999999999900 , p3 , 150 );// insert into works values ( 230101333333333333 , p4 , 250 );// select * from works ;// delete from works where pno = p1 ;// update works set pno = p0 ;// delete from works ;// drop table works ;public static void main(String[] args) throws IOException {String[] orderSplit;String analyzeOrder;while (true) {System.out.print("mysql>>");analyzeOrder = new Scanner(System.in).nextLine();orderSplit = analyzeOrder.split(" ");switch (orderSplit[0]) {case "create":createTable(orderSplit);break;case "insert":insertValue(orderSplit);break;case "drop":deleteTable(orderSplit);break;case "delete":deleteValue(orderSplit);break;case "select":showTableValue(orderSplit);break;case "update":updateValues(orderSplit);break;default:System.out.println("语法错误");break;}}}/*** @description: 创建表结构* create table works ( essn char , pno char , hours int );* create table project ( pname char , pnumber char , plocation char , dno char );* @date: 2023/11/1 13:18* @param: [orderSplit]* @return: void**///create table works ( essn char , pno char , hours int );public static void createTable(String[] orderSplit) throws IOException {if (orderSplit[1].equals("table")) {//判断语法正确性File file = new File("table.txt");if (file.exists()) {String fileName = orderSplit[2];//表名字File newFile = new File(fileName + ".txt");if (newFile.exists()) {System.out.println("表已存在");} else {newFile.createNewFile();FileWriter fileWriter = new FileWriter("table.txt", true);FileWriter newFileWriter = new FileWriter(fileName + ".txt", true);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);BufferedWriter newbufferWriter = new BufferedWriter(newFileWriter);bufferWriter.write(fileName);bufferWriter.write("\n");if (orderSplit[3].equals("(") && orderSplit[orderSplit.length - 1].equals(");")) {for (int i = 4; i < orderSplit.length - 2; i = i + 3) {newbufferWriter.write(orderSplit[i]);newbufferWriter.write(" ");}newbufferWriter.write("\n");} else {System.out.println("语法错误");}System.out.println(fileName + "表创建成功");bufferWriter.flush();newbufferWriter.flush();bufferWriter.close();newbufferWriter.close();}} else {System.out.println("文件不存在");}} else {System.out.println("语法错误");}}/*** @description: 插入数据* insert into works values ( 23010119751201312X , p1 , 100 );* insert into project values ( 研究项目 , p1 , 哈尔滨 , d1 );* @date: 2023/11/1 13:18* @param: [orderSplit]* @return: void**///insert into works values ( 23010119751201312X , p1 , 100 );public static void insertValue(String[] orderSplit) throws IOException {if (orderSplit[1].equals("into") && orderSplit[3].equals("values") && orderSplit[4].equals("(")) {String fileName = orderSplit[2];//表名字File file = new File(fileName + ".txt");if (file.exists()) {FileWriter fileWriter = new FileWriter(fileName + ".txt", true);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);for (int i = 5; i < orderSplit.length - 1; i++) {if (!orderSplit[i].equals(",")) {bufferWriter.write(orderSplit[i]);bufferWriter.write(" ");}}bufferWriter.write("\n");bufferWriter.flush();bufferWriter.close();System.out.println("插入成功");} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}/*** @description: 删除数据* delete from works where pno = p1 ;* delete from works ;* @date: 2023/11/1 13:18* @param: [orderSplit]* @return: void**///delete from works ;public static void deleteValue(String[] orderSplit) throws IOException {if (orderSplit[1].equals("from")) {String newString;String fileName = orderSplit[2];File file = new File(fileName + ".txt");if (file.exists()) {FileReader fileReader = new FileReader(fileName + ".txt");FileWriter fileWriter;if (orderSplit[3].equals("where")) {String tableString;BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> tableList = new ArrayList<>();while ((tableString = bufferedReader.readLine()) != null) {//如果当前行不包含orderSplit数组的倒数第二个元素if (!tableString.contains(orderSplit[orderSplit.length - 2])) {tableList.add(tableString);}}fileWriter = new FileWriter(fileName + ".txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);for (String tableName : tableList) {bufferWriter.write(tableName);bufferWriter.write("\n");}bufferWriter.flush();bufferWriter.close();bufferedReader.close();System.out.println("删除成功");} else {BufferedReader bufferedReader = new BufferedReader(fileReader);//读文件的第一行也就是表头newString = bufferedReader.readLine();fileWriter = new FileWriter(fileName + ".txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);bufferWriter.write(newString);bufferWriter.write("\n");bufferWriter.flush();bufferWriter.close();bufferedReader.close();System.out.println("删除成功");}} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}/*** @description: 删除表* drop table works ;* @date: 2023/11/1 13:18* @param: [orderSplit]* @return: void**///drop table works ;public static void deleteTable(String[] orderSplit) throws IOException {if (orderSplit[1].equals("table")) {String fileName = orderSplit[2];File file = new File(fileName + ".txt");if (file.exists()) {String tableString;FileReader fileReader = new FileReader("table.txt");BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> tableList = new ArrayList<>();while ((tableString = bufferedReader.readLine()) != null) {if (!tableString.equals(fileName)) {tableList.add(tableString);}}FileWriter fileWriter = new FileWriter("table.txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);for (String tableName : tableList) {bufferWriter.write(tableName);bufferWriter.write("\n");}bufferWriter.flush();bufferWriter.close();bufferedReader.close();file.delete();System.out.println("删除成功");} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}/*** @description: 展示表数据* select * from employee ;* @date: 2023/11/1 13:19* @param: [orderSplit]* @return: void**///select * from works ;public static void showTableValue(String[] orderSplit) throws IOException {if (orderSplit[1].equals("*") && orderSplit[2].equals("from")) {String fileName = orderSplit[3];File file = new File(fileName + ".txt");if (file.exists()) {String tableString;FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);System.out.println("------------------------" + fileName + "------------------------");while ((tableString = bufferedReader.readLine()) != null) {System.out.println(tableString);}System.out.println("------------------------" + fileName + "------------------------");bufferedReader.close();} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}/*** @description: 修改数据* update project set pnumber = p3 ;* @date: 2023/11/1 13:19* @param: [orderSplit]* @return: void**///update works set pno = p3 ;public static void updateValues(String[] orderSplit) throws IOException {if (orderSplit[2].equals("set")) {int index = 0;String fileName = orderSplit[1];File file = new File(fileName + ".txt");if (file.exists()) {String tableString;FileReader fileReader = new FileReader(fileName + ".txt");BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> tableList = new ArrayList<>();//将第一行按空格分割,并将其存储在字符串数组 firstLine 中String line = bufferedReader.readLine();String[] firstLine = line.split(" ");//遍历 firstLine 数组,查找 orderSplit 数组的第四个元素(即要更新的列名)// 所在的索引位置,并将其存储在 index 变量中for (int i = 0; i < firstLine.length; i++) {if (firstLine[i].equals(orderSplit[3])) {index = i;}}StringBuilder tem = new StringBuilder();// 将要更新的列的值用 orderSplit 数组的倒数第二个元素替换,// 然后将修改后的行重新组合成字符串,并将其存储在 tableList 中while ((tableString = bufferedReader.readLine()) != null) {String[] readLine = tableString.split(" ");readLine[index] = orderSplit[orderSplit.length - 2];for (String s : readLine) {tem.append(s).append(" ");}tableList.add(tem.toString());tem = new StringBuilder();}FileWriter fileWriter = new FileWriter(fileName + ".txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);bufferWriter.write(line);bufferWriter.write("\n");for (String table : tableList) {bufferWriter.write(table);bufferWriter.write("\n");}bufferWriter.flush();bufferWriter.close();bufferedReader.close();System.out.println("修改成功");} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}
}
第四部分:查询处理功能实践
(一)实验目的
1、熟悉SQL语句中的查询语句的格式和功能。
2、掌握查询处理算法,包括选择、投影、连接算法。
要求:能够处理多个表的连接操作;查询条件至少包括and、=、<、>等符号。
(二)实验内容
注:以下所有功能的实现,要进行语法和语义检查。
查询执行:
1、实现单关系的投影操作(SELECT 属性名列表 FROM 关系名)。
2、实现单关系的选择操作(SELECT * FROM 关系名 WHERE 条件表达式)。
3、实现单关系的选择和投影操作(SELECT 属性名列表 FROM 关系名 WHERE 选择条件)。//选择条件是指“属性名 操作符 常量”形式的条件
4、实现两个关系和多个关系的连接操作(SELECT * FROM 关系名列表 WHERE 连接条件)。//选择条件是指“属性名 操作符 属性名”形式的条件
5、实现两个关系和多个关系的选择和连接操作(SELECT * FROM 关系名列表 WHERE 选择条件和连接条件)。
6、实现两个关系和多个关系的投影和连接操作(SELECT 属性名列表 FROM 关系名列表 WHERE 连接条件)。
7、实现多个关系的选择、投影和连接操作(SELECT 属性名列表 FROM 关系名列表 WHERE 条件表达式)。
(三)实验代码
注意:和实验三一样创建一个空的table.txt 和src同级别
package cl.lh.sy4;import java.io.*;
import java.util.*;public class Sy4 {// 可以先把除了table.txt 之外的其他表删掉, 然后table内容清空// create table works ( essn char , pno char , hours int );// insert into works values ( 23010119751201312X , p1 , 100 );// insert into works values ( 23010119100000002X , p1 , 111 );// insert into works values ( 23010119111100002X , p2 , 151 );// insert into works values ( 288888888882010000 , p2 , 200 );// insert into works values ( 230199999999999900 , p3 , 150 );// insert into works values ( 230101333333333333 , p4 , 250 );// 仅能实现以下六种单表查询,无法连接多表// select * from works ;// select * from works where pno = p2 ;// select * from works where pno = p2 and hours = 200 ;// select essn from works ;// select essn from works where pno = p2 ;// select essn from works where pno = p2 and hours = 200 ;public static void main(String[] args) throws IOException {String[] orderSplit;String analyOrder;while (true) {System.out.print("mysql>>");analyOrder = new Scanner(System.in).nextLine();orderSplit = analyOrder.split(" ");switch (orderSplit[0]) {case "create":createTable(orderSplit);break;case "insert":insertValue(orderSplit);break;case "drop":deleteTable(orderSplit);break;case "delete":deleteValue(orderSplit);break;case "select":showTableValue(orderSplit);break;case "update":updateValues(orderSplit);break;default:System.out.println("语法错误");break;}}}/*** @description: 单表操作* @date: 2023/11/9 19:34* @param: [orderSplit]* @return: void**/public static void showTableValue(String[] orderSplit) throws IOException {if (orderSplit[1].equals("*") && orderSplit[2].equals("from")) {String fileName = orderSplit[3];File file = new File(fileName + ".txt");if (file.exists()) {if (orderSplit[4].equals("where")) {
// select * from works where pno = p2 and hours = 200 ;if (orderSplit[8].equals("and")) {//多关系连接String[] tableString, empSpilt;String empString;int flag = 0, valueIndex = 0;String[][] andString = new String[10][2];//利用二维数组存储连接起来的属性int andCount = 0;for (int i = 0; i < orderSplit.length; i++) {if (orderSplit[i].equals("=")) {andString[andCount][0] = orderSplit[i - 1];andString[andCount][1] = orderSplit[i + 1];andCount++;}}FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);tableString = bufferedReader.readLine().split(" ");for (String value : tableString) {for (int j = 0; j < andCount; j++) {if (value.equals(andString[j][0])) {flag++;}}if (flag == andCount) break;}for (int i = 0; i < tableString.length; i++) {if (tableString[i].equals(orderSplit[1])) {valueIndex = i;}}if (flag != andCount && valueIndex == 0) {System.out.println("属性不存在");return;} else {List<String> tableList = new ArrayList<>();while ((empString = bufferedReader.readLine()) != null) {if (empString.contains(andString[0][1])) {empSpilt = empString.split(" ");for (String s : empSpilt) {if (s.equals(andString[0][1])) {tableList.add(empString);}}}}String[] deString = new String[10];int deCount = 0;for (String tableName : tableList) {for (int i = 1; i < andCount; i++) {if (!(tableName.contains(andString[i][1]))) {deString[deCount] = tableName;deCount++;}}}for (int i = 0; i < deCount; i++) {tableList.remove(deString[i]);}System.out.println("+--------------------------------------------------+");for (String tableName : tableList) {System.out.println("| " + tableName + " |");}System.out.println("+--------------------------------------------------+");bufferedReader.close();}} else {// select * from works where pno = p2 ;String[] tableString;String empSplit;int flag = 0;FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);tableString = bufferedReader.readLine().split(" ");//判断属性名是否存在for (String s : tableString) {if (s.equals(orderSplit[orderSplit.length - 4])) {flag = 1;break;}}if (flag == 0) {System.out.println("不存在" + orderSplit[orderSplit.length - 4] + "属性名");return;} else {System.out.println("------------------------" + fileName + "------------------------");while ((empSplit = bufferedReader.readLine()) != null) {if (empSplit.contains(orderSplit[orderSplit.length - 2])) {System.out.println(empSplit);}}System.out.println("------------------------" + fileName + "------------------------");}bufferedReader.close();}} else {//select * from works ;String tableString;FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);System.out.println("------------------------" + fileName + "------------------------");while ((tableString = bufferedReader.readLine()) != null) {System.out.println(tableString);}System.out.println("------------------------" + fileName + "------------------------");bufferedReader.close();}} else {System.out.println("表不存在");}} else if (!orderSplit[1].equals("*") && orderSplit[2].equals("from")) {String fileName = orderSplit[3];File file = new File(fileName + ".txt");if (file.exists()) {int flag = 0;int valueIndex = 0;String[] tableString;String empString;String[] empSpilt;if (orderSplit[4].equals("where")) {if (orderSplit[8].equals("and")) {//多关系连接//select essn from works where pno = p2 and hours = 200 ;String[][] andString = new String[10][2];//利用二维数组存储连接起来的属性int andCount = 0;for (int i = 0; i < orderSplit.length; i++) {if (orderSplit[i].equals("=")) {andString[andCount][0] = orderSplit[i - 1];andString[andCount][1] = orderSplit[i + 1];andCount++;}}FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);tableString = bufferedReader.readLine().split(" ");for (String s : tableString) {for (int j = 0; j < andCount; j++) {if (s.equals(andString[j][0])) {flag++;}}if (flag == andCount) break;}for (int i = 0; i < tableString.length; i++) {if (tableString[i].equals(orderSplit[1])) {valueIndex = i;}}if (flag != andCount && valueIndex == 0) {System.out.println("属性不存在");return;} else {List<String> tableList = new ArrayList<>();while ((empString = bufferedReader.readLine()) != null) {if (empString.contains(andString[0][1])) {empSpilt = empString.split(" ");for (String s : empSpilt) {if (s.equals(andString[0][1])) {tableList.add(empString);}}}}String[] deString = new String[10];int deCount = 0;for (String tableName : tableList) {for (int i = 1; i < andCount; i++) {if (!(tableName.contains(andString[i][1]))) {deString[deCount] = tableName;deCount++;}}}for (int i = 0; i < deCount; i++) {tableList.remove(deString[i]);}System.out.println("+--------------------------+");System.out.println("| " + orderSplit[1] + " |");for (String tableName : tableList) {empSpilt = tableName.split(" ");System.out.println("| " + empSpilt[valueIndex] + " |");}System.out.println("+--------------------------+");bufferedReader.close();}} else {//单关系的选择和投影操作// select essn from works where pno = p2 ;int flag1 = 0;FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);tableString = bufferedReader.readLine().split(" ");for (int i = 0; i < tableString.length; i++) {if (tableString[i].equals(orderSplit[1])) {flag = 1;valueIndex = i;}if (tableString[i].equals(orderSplit[orderSplit.length - 4])) {flag1 = 1;}if (flag1 == 1 && flag == 1) break;}if (flag1 == 1 && flag == 1) {System.out.println("+--------------------------+");System.out.println("| " + orderSplit[1] + " |");while ((empString = bufferedReader.readLine()) != null) {if (empString.contains(orderSplit[orderSplit.length - 2])) {empSpilt = empString.split(" ");System.out.println("| " + empSpilt[valueIndex] + " |");}}System.out.println("+--------------------------+");} else {System.out.println("不存在" + orderSplit[1] + "属性名");return;}bufferedReader.close();}} else {// select essn from works ;FileReader fileReader = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(fileReader);tableString = bufferedReader.readLine().split(" ");for (int i = 0; i < tableString.length; i++) {if (tableString[i].equals(orderSplit[1])) {flag = 1;valueIndex = i;break;}}if (flag == 0) {System.out.println("不存在" + orderSplit[1] + "属性名");return;} else {System.out.println("+--------------------------+");System.out.println("| " + orderSplit[1] + " |");while ((empString = bufferedReader.readLine()) != null) {empSpilt = empString.split(" ");System.out.println("| " + empSpilt[valueIndex] + " |");}System.out.println("+--------------------------+");}bufferedReader.close();}}} else {System.out.println("语法错误");}}/*** @description: 建表* @date: 2023/11/5 17:56* @param: [orderSplit]* @return: void**/public static void createTable(String[] orderSplit) throws IOException {//建表if (orderSplit[1].equals("table")) {//判断语法正确性File file = new File("table.txt");if (file.exists()) {String fileName = orderSplit[2];//表名字File newFile = new File(fileName + ".txt");if (newFile.exists()) {System.out.println("表已存在");} else {newFile.createNewFile();FileWriter fileWriter = new FileWriter("table.txt", true);FileWriter newFileWriter = new FileWriter(fileName + ".txt", true);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);BufferedWriter newBufferWriter = new BufferedWriter(newFileWriter);bufferWriter.write(fileName);bufferWriter.write("\n");if (orderSplit[3].equals("(") && orderSplit[orderSplit.length - 1].equals(");")) {for (int i = 4; i < orderSplit.length - 2; i = i + 3) {newBufferWriter.write(orderSplit[i]);newBufferWriter.write(" ");}newBufferWriter.write("\n");} else {System.out.println("语法错误");}System.out.println("建表done");bufferWriter.flush();newBufferWriter.flush();bufferWriter.close();newBufferWriter.close();}} else {System.out.println("文件不存在");}} else {System.out.println("语法错误");}}/*** @description: 插值* @date: 2023/11/5 17:57* @param: [orderSplit]* @return: void**/public static void insertValue(String[] orderSplit) throws IOException {if (orderSplit[1].equals("into") && orderSplit[3].equals("values") && orderSplit[4].equals("(")) {String fileName = orderSplit[2];//表名字File file = new File(fileName + ".txt");if (file.exists()) {FileWriter fileWriter = new FileWriter(fileName + ".txt", true);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);for (int i = 5; i < orderSplit.length - 1; i++) {if (!orderSplit[i].equals(",")) {bufferWriter.write(orderSplit[i]);bufferWriter.write(" ");}}bufferWriter.write("\n");bufferWriter.flush();bufferWriter.close();System.out.println("插入成功");} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}/*** @description: 删值* @date: 2023/11/5 17:57* @param: [orderSplit]* @return: void**/public static void deleteValue(String[] orderSplit) throws IOException {if (orderSplit[1].equals("from")) {String newString;String fileName = orderSplit[2];File file = new File(fileName + ".txt");if (file.exists()) {FileReader fileReader = new FileReader(fileName + ".txt");FileWriter fileWriter;if (orderSplit[3].equals("where")) {String tableString;BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> tableList = new ArrayList<>();while ((tableString = bufferedReader.readLine()) != null) {if (!tableString.contains(orderSplit[orderSplit.length - 2])) {tableList.add(tableString);}}fileWriter = new FileWriter(fileName + ".txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);for (String tableName : tableList) {bufferWriter.write(tableName);bufferWriter.write("\n");}bufferWriter.flush();bufferWriter.close();bufferedReader.close();System.out.println("删除成功");} else {BufferedReader bufferedReader = new BufferedReader(fileReader);newString = bufferedReader.readLine();fileWriter = new FileWriter(fileName + ".txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);bufferWriter.write(newString);bufferWriter.write("\n");bufferWriter.flush();bufferWriter.close();bufferedReader.close();System.out.println("删除成功");}} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}/*** @description: 删表* @date: 2023/11/5 17:57* @param: [orderSplit]* @return: void**/public static void deleteTable(String[] orderSplit) throws IOException {if (orderSplit[1].equals("table")) {String fileName = orderSplit[2];File file = new File(fileName + ".txt");if (file.exists()) {String tableString;FileReader fileReader = new FileReader("table.txt");BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> tableList = new ArrayList<>();while ((tableString = bufferedReader.readLine()) != null) {if (!tableString.equals(fileName)) {tableList.add(tableString);}}FileWriter fileWriter = new FileWriter("table.txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);for (String tableName : tableList) {bufferWriter.write(tableName);bufferWriter.write("\n");}bufferWriter.flush();bufferWriter.close();bufferedReader.close();file.delete();System.out.println("删除成功");} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}/*** @description: 改值* @date: 2023/11/5 17:57* @param: [orderSplit]* @return: void**/public static void updateValues(String[] orderSplit) throws IOException {if (orderSplit[2].equals("set")) {int index = 0;String fileName = orderSplit[1];File file = new File(fileName + ".txt");if (file.exists()) {String tableString;FileReader fileReader = new FileReader(fileName + ".txt");BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> tableList = new ArrayList<>();String line = bufferedReader.readLine();String[] firstLine = line.split(" ");for (int i = 0; i < firstLine.length; i++) {if (firstLine[i].equals(orderSplit[3])) {index = i;}}StringBuilder tem = new StringBuilder();while ((tableString = bufferedReader.readLine()) != null) {String[] readLine = tableString.split(" ");readLine[index] = orderSplit[orderSplit.length - 2];for (String s : readLine) {tem.append(s).append(" ");}tableList.add(tem.toString());tem = new StringBuilder();}FileWriter fileWriter = new FileWriter(fileName + ".txt", false);BufferedWriter bufferWriter = new BufferedWriter(fileWriter);bufferWriter.write(line);bufferWriter.write("\n");for (String tableName : tableList) {bufferWriter.write(tableName);bufferWriter.write("\n");}bufferWriter.flush();bufferWriter.close();bufferedReader.close();System.out.println("修改成功");} else {System.out.println("表不存在");}} else {System.out.println("语法错误");}}
}
若觉得有帮助,欢迎点赞关注,一起成长进步~
声明:本文仅供学习交流,禁作商用;禁篡改、歪曲及有偿传播,引用需标明来源。侵权必究。
