一. Oracle数据库对象
实验目的
Oracle 数据库包含许多数据库对象,例如表、视图、索引、序列、存储过程、触发器等。表、视图、索引的操作在前面的实验中已经做了相应的练习,本实验将介绍如何使用序列、触发器和存储过程。同学们可以通过本实验掌握如何定义、使用删除这些数据库对象。
实验内容
1、 以SYSTEM连接数据库ORCL,执行以下语句查看对象:
select object_name,owner from all_objects where owner = 'SYSTEM';
显示有多少行?
435行
2、 创建新的用户并授权:
create user cc identified by ccpassword ;
grant resource, connect, DBA to cc;
成功
3、 以用户CC的身份建立连接,并在此连接下执行序列的操作:
select object_name,owner from all_objects where owner = 'SYSTEM';
显示有多少行?
也是435行。
select object_name,owner from all_objects where owner = 'CC';
显示有多少行?
1行
create sequence my_seq_01 increment by 1 start with 1 nomaxvalue nocycle;
create sequence my_seq_02 increment by 2 start with 1;
select object_name,owner from all_objects where owner = 'CC';
显示有多少行?
3行。
select object_name,Object_Type, owner from all_objects where owner = 'SYSTEM' and OBJECT_TYPE='SEQUENCE';
显示有多少行?
Select Object_Name, Object_Type, Owner From All_Objects Where Owner = 'CC' and OBJECT_TYPE='SEQUENCE';
显示有多少行?
2行。
select my_seq_01.nextval from dual;
重复执行上面的这条语句,得到什么序列? 1,2,3,4,……
dual是一个虚拟表,用来构成select的语法规则
alter sequence my_seq_01 increment by 10 ;
select my_seq_01.nextval from dual;
重复执行上面的这条语句,得到什么序列?
14,24,34,44,……从上一个值继续
select my_seq_02.nextval from dual;
重复执行上面的这条语句,得到什么序列? 1,3,5,7,……
drop sequence my_seq_02;
select my_seq_02.nextval from dual;
create sequence my_seq_02 increment by 3 start with 100;
select my_seq_02.nextval from dual;
重复执行上面的这条语句,得到什么序列? 100,103,106,109,……与上面被删除的同名序列没有关系了。
4、 在CC的连接中,执行存储过程的操作;
Declare
tmp integer default 0;
Begin
select count(*) into tmp from user_tables where table_name='SC';
if(tmp>0) then
execute immediate 'drop table SC ';
end if;
select count(*) into tmp from user_tables where table_name='STUDENT';
if(tmp>0) then
execute immediate 'drop table STUDENT ';
end if;
select count(*) into tmp from user_tables where table_name='COURSE';
if(tmp>0) then
execute immediate 'drop table COURSE ';
end if;
Select count(*) into tmp From All_Objects Where OBJECT_NAME='SC_INS' and OBJECT_TYPE='PROCEDURE';
if(tmp>0) then
execute immediate 'drop PROCEDURE SC_INS ';
end if;
Select count(*) into tmp From All_Objects Where OBJECT_NAME='STUDENT_NO' and OBJECT_TYPE='SEQUENCE';
if(tmp>0) then
execute immediate 'drop SEQUENCE STUDENT_NO ';
end if;
end;
然后重新创建数据表:
create table student(sno int primary key, sname varchar(8));
create table course(cno int primary key, cname varchar(10));
create table sc(sno int, cno int, grade int,
primary key(sno,cno),
foreign key (sno) references student(sno), foreign key (cno) references course(cno));
成功了吗?上面的三个表的创建顺序能否任意调整?
成功了,不能任意跳转调整顺序,sc最后建立。
select object_name, Object_Type, owner from all_objects where owner = 'CC';
显示有多少行?索引是怎么产生的?
3行索引,主码建立索引。
查看SC表的索引,有哪些列来确定?依据是什么?索引名是什么?
由各表的主码确定,这里索引名是系统分配如上。
create sequence student_no increment by 1 start with 2012001;
insert into student values(student_no.nextval, 'aaaaaa');
insert into student values(student_no.nextval,'bbbbbbb');
insert into student values(student_no.nextval,'ccccccc');
insert into student values(student_no.nextval,'ddddddd');
commit;
select * from student;
insert into course values (105,'程序设计');
insert into course values (908,'大学英语');
insert into course values (433,'数据结构');
commit;
select * from course;
create procedure sc_ins(ino int,cno int,grade int) is
begin
if(grade>=0) then insert into sc values (ino,cno,grade);
else insert into sc values (ino,cno,null);
end if;
end;
成功了吗? 显示什么内容?
Select Object_Name, Object_Type, Owner From All_Objects Where Owner = 'CC' and OBJECT_TYPE='PROCEDURE';
显示有多少行?
exec sc_ins (2012001,105,60);
exec sc_ins (2012001,908,0);
exec sc_ins (2012001,433,98);
exec sc_ins (2012002, 105,75);
exec sc_ins (2012002, 433,-1);
exec sc_ins (2012003, 105,64);
exec sc_ins (2012003, 908,90);
exec sc_ins (2012003, 433,-100);
select student.sno,sname,cname,grade
from student,course,sc
where student.sno=sc.sno and course.cno=sc.cno;
显示结果说明,成绩为负数的话,在数据表里是什么内容?存储过程有什么好处?
分数为0,和分数为负数,有区别吗?
负数不显示,为NULL,存储在三个表中,利用过程引用,方便插入修改。
5、 在CC的连接中,执行触发器的操作;
触发器只影响当前表:
alter table sc add (gradelevel char(1));
update sc set gradelevel='A' where grade>=85;
update sc set gradelevel='B' where grade>=75 AND grade<85;
update sc set gradelevel='C' where grade>=60 AND grade<75;
update sc set gradelevel='D' where grade<60;
select student.sno,sname,cname,grade,gradelevel
from student,course,sc
where student.sno=sc.sno and course.cno=sc.cno;
create or replace trigger sc_ins before insert or update on sc
for each row
begin
if :new.grade>=85 then :new.gradelevel:='A';
else if :new.grade>=75 then :new.gradelevel:='B';
else if :new.grade>=60 then :new.gradelevel:='C';
else if :new.grade>=60 then :new.gradelevel:='D';
end if;
end if;
end if;
end if;
end;
执行成功了吗?
select * from sc where sno=2012002;
insert into sc(sno,cno,grade) values (2012002,908,80);
select * from sc where sno=2012002;
刚刚插入的行,gradelevel列的值哪里来的?
来自sc_ins触发器.
触发器影响其他表:
alter table course add (maxgrade int);
update course set maxgrade=0;
select * from course;
create or replace trigger course_ins before insert or update on sc
for each row
declare oldg int;
begin
select maxgrade into oldg from course where cno=:new.cno;
if oldg<:new.grade then update course set maxgrade=:new.grade where cno=:new.cno;
end if;
end course_ins;
触发器生成成功了吗?当前触发器的目录下有多少项?
2项
select * from course;
记下当前各科的最高分数
insert into sc(sno,cno,grade) values (2012004,908,99);
insert into sc(sno,cno,grade) values (2012004,433,88);
insert into sc(sno,cno,grade) values (2012004,105,59);
select * from sc;
select * from course;
2012004号同学的三科分数插入成功了吗?
当前各科的最高分有没有变化?
插入成功,最高分改变。
select * from sc where sno=2012003 and cno=105;
2012003号同学的105号课程的分数是多少?级别是什么?
update sc set grade=100 where sno=2012003 and cno=105;
select * from sc where sno=2012003 and cno=105;
select * from course;
2012003号同学的105号课程的分数修改成功了吗?级别(sc.gradelevel)有没有相应变化?当前各科的最高分(course.maxgrade)有没有变化?
一个修改语句,可以同时触发两个表的数据改变吗?
两个表改变。
两处地方均可查看当前的触发器:
补充知识:
语句级触发器
在默认情况下创建的DML 触发器为语句级触发器,即触发事件发生后,触发器只执行一次。在语句级触发器不能对列值进行访问和操作,也不能获取当前行的信息如果触发器响应多个DML 事件,而且需要根据事件的不同进行不同的操作,则可以在触发器体中使用3 个条件谓词,即INSERTING、UPDATING、DELETING。
行级触发器
行级触发器是指执行DML 操作时,每操作一个记录,触发器就执行一次,一个DML操作涉及多少个记录,触发器就执行多少次。在行级触发器中可以使用WHEN 条件,进一步控制触发器的执行。在行级触发器中引入了:old 和:new 两个标识符,来访问和操作当前被处理记录中的数据。:old 和:new 是DML 语句对应表的行记录类型。在不同触发事件中,:old 和:new 的意义不同。在执行部分引用使用:old.field 和:new.field,在WHEN 条件中使用则不带冒号。
鼓励自己组织、设计操作流程。
二. 数据备份与恢复
实验目的
掌握ORACLE数据库系统的一种备份/恢复方法。
实验内容
提示(黄色底的代码可以直接粘贴运行):
1、 在orcl数据库中创建新的用户并授权(如果原来已有这个用户,可以忽略本步骤):
create user cc identified by ccpassword ;
grant resource, connect, DBA to cc;
成功。
2、 以用户CC的身份建立连接,并在此连接下执行后面的操作;
3、 拷贝代码运行,删去旧的同名数据表:
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;
4、 拷贝代码运行,建立表格及输入数据:
create table Reader
(
RNO varchar2(4) primary key,
Rname varchar2(10) not null,
Rsex varchar2(2),
Rage integer,
Rboss varchar2(10),
Raddress varchar2(30)
) ;
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');
create table Book
(
BNO varchar2(4),
Bname varchar2(50) not null,
Bauthor varchar2(50),
Bpress varchar2(50),
Bprice numeric(6,2),
primary key(BNO)
);
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);
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)
);
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');
5、 以CC的身份连接,确认orcl数据库中有这三个数据表,以及相应的数据
6、 打开“Database Configuration Assistant”
输入数据库名“mydb”
要记住这个密码啊!
口令要求
oracle口令设置有以下规范和建议:
口令至少包含一个小写字母,至少包含一个大写字母。 至少包含一个数字。 长度至少为 8 个字符。 使用可包括下划线 (_), 美元符号 ($) 和井号 (#) 字符的数据库字符集。 如果包含特殊字符 (包括以数字或符号作为口令的开头), 请将口令加双引号。 不应为实际单词。
7、 确认D盘有文件“export from orcl.sql”
8、 到ORACLE SQL DEVELOPER中以SYSTEM用户的身份建立新的连接(这个密码是前面自己新建数据库输入的密码):
9、 在该连接下执行以下语句,即在数据库MYDB里增加用户CC,以便与备份的用户名一致(打开文件“export from orcl.sql”可见里面的语句带了用户名):
create user cc identified by ccpassword ;
grant resource, connect, DBA to cc;
10、 以用户CC的身份建立新的连接到数据库mydb:
11、 确认mydb中没有数据表READER、BOOK、RB:
12、 在MYDB的CC用户连接中打开文件(或用记事本打开再复制粘贴)运行
成功。
13、 确认MYDB中含有这三个表,且表的内容、约束等与数据库ORCL中的一致
14、 为避免占用太多的系统资源,删去数据库MYDB。先删去有关MYDB的所有连接
如果按照上述步骤,应该有两个连接:SYSTEM用户的连接和CC用户的连接。
15、 打开“Database Configuration Assistant”
16、 删去数据库MYDB:
Mydb已删除。
注意:如果未删除数据库的连接,则无法删除数据库。
Oracle数据库有三种标准的备份方法:
导出/导入
热备份(被备份的数据库不必关闭)
冷备份(被备份的数据库必须关闭)
导出备件是一种逻辑备份, 冷备份和热备份是物理备份。
我们这里做的属于逻辑备份。物理备份是指文件级的备份,有兴趣的同学可以查阅ORACLE的有关手册。
三. 事务管理
实验目的
事务是由用户定义的一个数据库的操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。 Oracle数据库使用事务机制来确保数据的一致性,数据库的事务机制是发生在第一个SQL语句执行时,结束于COMMIT或ROLLBACK命令执行时。只有一个事务执行完成后,另一个可执行的SQL语句才能执行。SQL执行时,所有的数据改变都是暂时的,只有结束事务的时候,才会真正写入数据库。
通过本实验,对事务管理有感性认识。
实验内容
提示(黄色底的代码可以直接粘贴运行):
1、 用帐号sys密码oracle创建新的用户并授权:
create user cc identified by ccpassword ;
grant resource, connect, DBA to cc;
2、 以用户CC的身份建立连接,并在此连接下执行后面的操作;
create table mytable(tno char(2) primary key, tname char(8));
3、 拷贝代码运行,建立表格及输入数据:
Insert Into Mytable Values('01','赵老大');
select * from mytable;
Insert Into Mytable Values('02','赵老二');
select * from mytable;
Insert Into Mytable Values('03','赵老三');
select * from mytable;
表中共有多少行数据?
最后有3行。
Insert Into Mytable Values('04','钱老大');
select * from mytable;
Insert Into Mytable Values('05','钱老二');
select * from mytable;
Rollback;
select * from mytable;
回退到哪里?表中剩下多少行数据?
回退到插入数据前,没有数据。
Insert Into Mytable Values('01','赵老大');
select * from mytable;
Insert Into Mytable Values('02','赵老二');
select * from mytable;
Insert Into Mytable Values('03','赵老三');
select * from mytable;
commit;
Insert Into Mytable Values('04','钱老大');
select * from mytable;
Insert Into Mytable Values('05','钱老二');
select * from mytable;
Rollback;
select * from mytable;
回退到commit,提交commit之前的数据,不会回退。
Insert Into Mytable Values('04','钱老大');
Savepoint p1;
select * from mytable;
Insert Into Mytable Values('05','钱老二');
Savepoint p2;
select * from mytable;
Insert Into Mytable Values('06','钱老三');
select * from mytable;
Rollback to p2;
select * from mytable;
Rollback to p1;
select * from mytable;
Rollback to p2;(回退p2),则回退到p2后面的指令执行前,就是回到p2当前行。相当于一个断点,回到这个断点。