数据库实验二 SQL语言

时间:2024-04-06 18:10:05

实验二

SQL语言

实验目的

熟悉并掌握创建表,插入记录,查询记录,删除记录,修改记录。

创建索引,删除索引。

创建视图,使用视图,删除视图。

 

实验内容

现有一个单位内部的小型图书借阅系统,假设每本图书的数量无限制,并且可以借给任何单位成员,每个单位成员可以借多本书,单位成员与图书的关系是多对多的关系。假设系统中仅有三个关系模式。

数据表结构

Reader

属性名

类型

长度

是否空

含义

RNO

varchar2

4

 

员工编号(主码)

Rname

varchar2

10

员工姓名

Rsex

varchar2

2

 

性别

Rage

integer

integer

 

年龄

Rboss

varchar2

10

 

直接上司

Raddress

varchar2

30

 

办公地点

Book

属性名

类型

长度

是否空

含义

BNO

varchar2

4

 

书本编号(主码)

Bname

varchar2

50

书名

Bauthor

varchar2

50

 

作者

Bpress

varchar2

50

 

出版社

Bprice

varchar2

numeric(6,2)

 

价格

RB

属性名

类型

长度

是否空

含义

RNO

varchar2

4

 

员工编号

BNO

varchar2

4

 

书本编号

RBdate

date

 

 

借阅日期

 

 

 

 

 

部分提示(黄色底的代码可以直接粘贴运行):

  1. 创建新的用户并授权:

create user cc identified by ccpassword ;

grant resource, connect, DBA  to cc;

  1. 以用户CC的身份建立连接,并在此连接下执行后面的操作;
  2. 拷贝代码运行,删去旧的同名数据表:

Declare

tmp integer default 0;

Begin

select count(*) into tmp from user_tables where table_name='RB';

if(tmp>0) then

execute immediate 'drop table RB';

end if;

select count(*) into tmp from user_tables where table_name='READER';

if(tmp>0) then

execute immediate 'drop table READER';

end if;

select count(*) into tmp from user_tables where table_name='BOOK';

if(tmp>0) then

execute immediate 'drop table BOOK';

end if;

end;

 

问:为何要先删去RB?能不能先删去READER?

  1. 建立表格Reader

create table Reader

(

    RNO      varchar2(4) primary key,

    Rname    varchar2(10) not null,

    Rsex       varchar2(2),

    Rage       integer,

    Rboss     varchar2(10),

    Raddress varchar2(30)

) ;

  1. 拷贝代码运行,向Reader表格中插入十条数据

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R001','张三',20,'男','李四','416');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R002','张三',35,'女',null,'417');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R003','李四',30,'男',null,'416');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R004','王五',20,'男',null,'417');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R005','马六',40,'男',null,'416');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R006','刘三',20,'男',null,'417');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R007','王四',40,'男','李四','416');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R008','李小龙',20,'男','李四','417');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R009','王小倩',40,'男','李四','416');

insert into Reader (RNO,Rname,Rage,Rsex,Rboss, Raddress) values('R010','王一小',20,'男','李四','417');

  1. 查询记录:在Reader表中查询直接上司是“李四”的员工的名字

select Rname from Reader where Rboss='李四';

  1. 修改记录:在Reader表中把直接上司是“李四”的员工的办公地点统一改为“420

UPDATE reader SET Raddress='420' WHERE rboss='李四';

  1. 删除记录:在Reader表中把直接上司未赋值(NULL)是记录删去

DELETE FROM reader WHERE rboss=NULL;

  1. 删去数据表:把整个Reader表删去

DROP TABLE reader;

  1. 重新执行第一、二步,即建立数据表、插入数据。

 

  1. 创建表格Reader2,比较Reader2Reader中的记录和结构是否相同

create table reader2 as select *  from reader; --创建表格reader2

查看这两个数据表的结构、内容是否相同?分别执行:

desc reader;

数据库实验二 SQL语言

desc reader2;

数据库实验二 SQL语言

也可以在可视化界面查看这两个表所附带的约束

数据库实验二 SQL语言

  1. 分别执行下面的每行语句,查看语句是否执行成功,分析为什么?

update reader set RNO='R001' where Rname='张三';

数据库实验二 SQL语言

表reader中的RNO是primary key,更新后的RNO与现存的RNO重复,违反唯一约束条件

 

update reader2 set RNO='R001' where Rname='张三';

数据库实验二 SQL语言

insert into reader2(RNO,Rname,Rsex,Rage,Rboss, Raddress) values(null,'lisi',null,null,null,null);

数据库实验二 SQL语言

READER2

数据库实验二 SQL语言

数据库实验二 SQL语言

 

  1. 删除Reader2表格;

DROP TABLE READER2;

  1. 拷贝代码运行,建立表格Book

create table Book

(

    BNO      varchar2(4),

    Bname    varchar2(50) not null,

    Bauthor  varchar2(50),

    Bpress    varchar2(50),

    Bprice    numeric(6,2),

    primary key(BNO)

);

数据库实验二 SQL语言

  1. 拷贝代码运行,向Book表格中插入5条数据

insert into book (BNO,Bauthor,Bname, bpress, bprice) values('B001','严蔚敏','数据结构','清华大学出版社',null);

insert into book (BNO,Bauthor,Bname, bpress, bprice) values('B002','唐发根','数据结构','北航出版社',24);

insert into book (BNO,Bauthor,Bname, bpress, bprice) values('B003','王珊','数据库原理','高等教育出版社',40);

insert into book (BNO,Bauthor,Bname, bpress, bprice) values('B004','张飞','数据库原理','清华大学出版社',30);

insert into book (BNO,Bauthor,Bname, bpress, bprice) values('B005','王珊','数据库原理','清华大学出版社',null);

  1. 拷贝代码运行,建立表格RB

create table RB

(

    RNO varchar2(4),

    BNO varchar2(4),

    RBdate date default sysdate,

    primary key(RNO,BNO),

    foreign key (RNO) references Reader(RNO),

    foreign key (BNO) references Book(BNO)

);

  1. 拷贝代码运行,向RB表格中插入13条数据;

insert into RB (RNO,BNO) values ('R001','B001');

insert into RB (RNO,BNO) values ('R001','B002');

insert into RB (RNO,BNO) values ('R001','B004');

insert into RB (RNO,BNO) values ('R002','B001');

insert into RB (RNO,BNO) values ('R003','B001');

insert into RB (RNO,BNO) values ('R004','B001');

insert into RB (RNO,BNO) values ('R004','B002');

insert into RB (RNO,BNO) values ('R005','B001');

insert into RB (RNO,BNO) values ('R006','B001');

insert into RB (RNO,BNO) values ('R006','B003');

insert into RB (RNO,BNO) values ('R006','B005');

insert into RB (RNO,BNO) values ('R006','B002');

insert into RB (RNO,BNO) values ('R006','B004');

初始数据

reader

RNO

RNAME

RSEX

RAGE

RBOSS

RADDRESS

R001

张三

20

李四

416

R002

张三

35

 

417

R003

李四

30

 

416

R004

王五

20

 

417

R005

马六

40

 

416

R006

刘三

20

 

417

R007

王四

40

李四

416

R008

李小龙

20

李四

417

R009

王小倩

40

李四

416

R010

王一小

20

李四

417

 

book表中数据

BNO

BNAME

BAUTHOR

BPRESS

BPRICE

B002

数据结构

唐发根

北航出版社

24

B003

数据库原理

王珊

高等教育出版社

40

B004

数据库原理

张飞

清华大学出版社

30

B005

数据库原理

王珊

清华大学出版社

 

B001

数据结构

严蔚敏

清华大学出版社

 

 

RB表中数据

RNO

BNO

RBDATE(实验时间)

R001

B001

插入数据时的系统时间

R001

B002

 

R001

B004

 

R002

B001

 

R003

B001

 

R004

B001

 

R004

B002

 

R005

B001

 

R006

B001

 

R006

B003

 

R006

B005

 

R006

B002

 

R006

B004

 

 

以下为查询READER表中创建的约束类型,其中constraint_type为约束类型,该属性值的取值Type Code如下表所示。(可以根据上课所讲的实体完整性、参照完整性、用户自定义完整性理解以下约束类型;直接在SQL DEVELOPER中双击表格也可以查看在表上所建立的约束)

select table_name,constraint_name,constraint_type from user_constraints where table_name ='READER';

数据库实验二 SQL语言

 

Type Code

Type Description

Acts On Level

C

Check on a table

Column

O

Read Only on a view

Object

P

Primary Key

Object

R

Referential AKA Foreign Key

Column

U

Unique Key

Column

V

Check Option on a view

Object

 

  1. 执行insert into RB(RNO,BNO) values('R010','B005');
  2. 写出删除Reader表格中编号为’R010’的员工,如果执行错误,分析错误原因。
  3. 想办法删除Reader中的’R010’员工;

方法一:先把RB中所有’R010’的借书记录都删掉

方法二:修改数据表READER的结构,允许级联删除(注:ORACLE不支持级联更新)。

alter table rb add constraint MYFK foreign key(rno) references reader(rno) on delete cascade;

数据库实验二 SQL语言

系统提示:SQL 错误: ORA-02275: 此表中已经存在这样的引用约束条件

 

可见,首先要先删去原来的约束,因建表时没给该约束命名,故应查这个约束的名字,才能删去。注意,这个名字由系统自动赋值,不同的环境下约束名可能不同):

数据库实验二 SQL语言

alter table rb drop constraint SYS_C0011303;

数据库实验二 SQL语言

alter table rb add constraint MYFK foreign key(rno) references reader(rno) on delete cascade;

数据库实验二 SQL语言

数据库实验二 SQL语言

 

再执行:delete from reader where rno='R010';

数据库实验二 SQL语言

顺利删去一行,打开RB表,发现前面插入的('R010','B005')也不在了。

数据库实验二 SQL语言

  1. Reader表添加一个属性列“出生年份”,名为Rbirthday,整数;

alter table reader ADD Rbirthday integer ;

数据库实验二 SQL语言

  1. 对于Reader表格,员工编号可以确定年龄,年龄又可以确定出生年份,因此存在传递函数依赖关系,删除Rbirthday列,使关系模式符合第三范式要求;

 

alter table reader DROP column Rbirthday;

数据库实验二 SQL语言

  1. 修改Reader表格的Raddress属性,使其长度为50,数据类型不变;

alter table reader modify Raddress varchar2(50);

  1. 修改book表的Bprice属性,使其值得范围在10100之间;

alter table book add constraint bp check (Bprice BETWEEN 10 and 100);

  1. 修改Reader表的Rage属性,使其值得范围为1660之间。

alter table Reader add constraint rr check (Rage BETWEEN 16 and 60);

  1. 试试是否可以删除Reader表,使用CASCADE是否可以删除?

drop table reader CASCADE;

drop table reader CASCADE CONSTRAINTS;

数据库实验二 SQL语言

  1. 删除ReaderBookRB表。

drop table rb CASCADE CONSTRAINTS;

数据库实验二 SQL语言

drop table book CASCADE CONSTRAINTS;

数据库实验二 SQL语言

索引的建立与删除

  1. 重新执行前面的代码创建三个数据表并插入数据;
  2. Reader表格的Rname建立UNIQUE索引

create unique index myindex on reader(rname);

数据库实验二 SQL语言

报告出错:"cannot CREATE UNIQUE INDEX; duplicate keys found"

如何修改表格数据,再建索引

 解决方法很简单,要么把数据库的数据清理掉;要么把你要创建唯一索引的那一列重复的数据删掉。我选择的是创建唯一索引的那一列重复的数据删掉一个。

  1. 删除索引。

drop index myindex;

数据库实验二 SQL语言

视图

  1. 如果上面的运行是在CC的连接中,则需要回到在sysdba 的连接中,执行:

grant resource, connect, DBA  to cc;

否则系统显示没有创建视图的权限。执行完之后再回到CC的连接:

ORACLE SQL Developer 的左上方: 数据库实验二 SQL语言

  1. 建立在416办公室工作的视图V416,视图包括员工的编号、姓名、年龄等信息

CREATE VIEW V416 as select rno,rname,rage from reader where raddress='416'

数据库实验二 SQL语言

确认该视图的存在:

select * from v416

数据库实验二 SQL语言

  1. V416中查询年龄大于30的员工信息

SELECT rno,rname from v416 WHERE rage>30;

数据库实验二 SQL语言

  1. 向视图V416中插入一条新的员工记录,然后从V416中查找该条记录,测试是否可以找到;

insert into v416( rno,rname,rage) values('R999','new reader',99);

select * from reader

数据库实验二 SQL语言

select * from v416

数据库实验二 SQL语言

插入成功了吗?为什么通过视图插入的纪录在视图中看不见?

刚插入数据条件不满足此视图的条件了

数据库实验二 SQL语言

  1. 建立在417办公室工作的视图V417,视图包括员工的编号、姓名、性别、年龄等信息,视图定义带with check option选项;

CREATE VIEW V417 as select rno,rname,rsex,rage,raddress from reader where raddress='417' with check option;

数据库实验二 SQL语言

select * from v417

数据库实验二 SQL语言

  1. 向视图V417中插入一条新的员工记录,然后从V417中查找该条记录,测试是否可以找到;

insert into v417( rno,rname,rage) values('R777','417 reader',66);

数据库实验二 SQL语言

执行不成功。

drop view v417;

CREATE VIEW V417 as select rno,rname,rsex,rage,raddress from reader where raddress='417' with check option;

insert into v417( rno,rname,rage,raddress) values('R777','417 reader',66,'417');

执行成功。

数据库实验二 SQL语言

  1. 通过视图删除刚插入的员工记录,在基本表Reader中查看是否已经删除成功?

select * from v416;

数据库实验二 SQL语言

delete from v416 where rname='王小倩';

数据库实验二 SQL语言

select * from v416;

数据库实验二 SQL语言

数据库实验二 SQL语言

  1. 在视图V417上建立所有女员工信息的视图FV417,查询视图结果

CREATE VIEW FV417 as select * from V417 where RSEX='女';

数据库实验二 SQL语言

select * from FV417;

数据库实验二 SQL语言

  1. 删除视图V417中没有借阅图书的员工信息

SELECT * FROM V417;

数据库实验二 SQL语言

Delete from v417 where v417.rno not in (SELECT rno from rb);

数据库实验二 SQL语言

SELECT * FROM V417;

数据库实验二 SQL语言

  1. 建立视图GV,数据包括每本图书的编号及其借阅数量。思考是否可以向GV中插入数据,为什么?

SELECT BNO,COUNT(*) FROM RB GROUP BY BNO;

数据库实验二 SQL语言

 CREATE VIEW GV(BNO,COUNTS)  AS  SELECT BNO,COUNT(*) FROM RB GROUP BY BNO;

数据库实验二 SQL语言

 SELECT * FROM GV;

数据库实验二 SQL语言

思考是否可以向GV中插入数据,为什么?

不可以向GV插入数据,因为GV的内容并非数据,而是数据和相关数据统计结果。

  1. 删除视图V417

drop view v417

数据库实验二 SQL语言

 

触发器(可不做,时间多再做)

参考PLSQL帮助文档,试试建立一个触发器。在用户执行删除某个员工的时候触发,该触发器的功能是先删除RB中该员工的借书记录,然后删除Reader中该员工记录。

实验报告要求

写出实验步骤及相关的SQL语句即可。