一、实验目的
1. 对ORACLE数据库系统的用户权限管理有感性认识。
2. 事务是由用户定义的一个数据库的操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。 Oracle数据库使用事务机制来确保数据的一致性,数据库的事务机制是发生在第一个SQL语句执行时,结束于COMMIT或ROLLBACK命令执行时。只有一个事务执行完成后,另一个可执行的SQL语句才能执行。SQL执行时,所有的数据改变都是暂时的,只有结束事务的时候,才会真正写入数据库。通过本实验,对事务管理有感性认识。
二、实验原理
Oracle 权限设置
一、权限分类:
系统权限:
系统规定用户使用数据库的权限。(系统权限是对用户而言)。
实体权限:
某种权限用户对其它用户的表或视图的存取权限(针对表或视图而言)。
二、系统权限管理:
1、系统权限分类:
DBA:拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构。
RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构。
CONNECT:拥有Connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构。
对于普通用户:授予connect, resource权限。
对于DBA管理用户:授予connect,resource, dba权限。
2、系统权限授权命令:
系统权限只能由DBA用户授出:sys, system(最开始只能是这两个用户)
授权命令:grant connect, resource, dba to 用户名1 [,用户名2]…;
普通用户通过授权可以具有与system相同的用户权限,但永远不能达到与sys用户相同的权限,system用户的权限也可以被回收。
例:以system用户身份连接数据库之后,执行:
create user cc identified by ccpassword ;
grant resource, connect, DBA to cc;
查询用户拥有哪里权限:
select * from dba_role_privs;
select * from dba_sys_privs;
select * from role_sys_privs;
删除用户: drop user 用户名 cascade;
//加上cascade则将用户连同其创建的东西全部删除
3、系统权限传递:
增加WITH ADMIN OPTION选项,则得到的权限可以传递。
grant connect, resource to CC with admin option; //可以传递所获权限
4、系统权限回收:系统权限只能由DBA用户回收
Revoke dba, resource from CC;
5、删除用户
drop user 用户名; //用户没有建任何实体
drop user 用户名 CASCADE; // 将用户及其所建实体全部删除
说明:当前正连接的用户不得删除。
三、实体权限管理
1、实体权限分类:
select, update, insert, alter, index, delete, all //all包括所有权限
execute //执行存储过程权限
user01:
grant select, update, insert on product to user02;
grant all on product to user02;
user02:
select * from user01.product;
// 此时user02查user_tables(连接中能显示的),不包括user01.product这个表,但如果查all_tables则可以查到,因为他可以访问。
2. 将表的操作权限授予全体用户:
grant all on product to public;
// public表示是所有的用户,这里的all权限不包括drop。
select owner, table_name from all_tables; // 用户可以查询的表
select table_name from user_tables; // 用户创建的表
select grantor, table_schema, table_name, privilege from all_tab_privs;
// 获权可以存取的表(被授权的)
select grantee, owner, table_name, privilege from user_tab_privs;
// 授出权限的表(授出的权限)
3. DBA用户可以操作全体用户的任意基表(无需授权,包括删除):
DBA用户:
Create table stud02.product(id number(10), name varchar2(20));
drop table stud02.emp;
create table stud02.employee as select * from scott.emp;
4. 实体权限传递(with grant option):
user01:
grant select, update on product to user02 with grant option;
// user02得到权限,并可以传递。
5. 实体权限回收:
user01:
Revoke select, update on product from user02; //传递的权限将全部丢失。
说明:如果取消某个用户的对象权限,那么对于这个用户使用WITH GRANT OPTION授予权限的用户来说,同样还会取消这些用户的相同权限,也就是说取消授权时级联的。
三、使用仪器、材料
Oracle 11g,windows10;
四、实验步骤
1、以SYSTEM身份连接到orcl数据库,创建新的用户并授权(如果原来已有这个用户,可以忽略本步骤):
2、以用户CC的身份建立连接,并在此连接下执行后面的操作;
select * from user_role_privs;
可以看到自己的权限,有多少种权限?
3、在CC连接中:拷贝代码运行,删去旧的同名数据表(如果是新创建的用户,此步骤可以省略):
4、在CC连接中:拷贝代码运行,建立表格及输入数据:
5、在CC连接中:确认orcl数据库中有这三个数据表,以及相应的数据
6、在CC连接中:查询用户CC的权限信息(每句单独执行):
7、在CC连接中:查询用户创建的表
8、在CC连接中:删去数据表BR,成功吗?
再次执行:
select table_name from user_tables;
显示什么结果?
9、回收用户CC的部分权限:以SYSTEM的身份连接(可以在SQL DEVELOPER的右上角切换),在此连接中执行
Revoke dba, resource from CC;
10、以CC的身份连接数据库(可以在SQL DEVELOPER的右上角选择连接),执行:Create Table Aa(cola int);
成功吗?为什么?
11、切换为SYSTEM的连接,执行切换为SYSTEM的连接,执行
grant resource to CC;
12、切换为CC的连接,执行
select * from user_role_privs;
可以看到自己的权限,有多少种权限?
Create Table Aa(cola int);
成功吗?为什么?
13、切换为SYSTEM的连接,执行
DROP USER CC;
成功吗?为什么?
14、删除连接CC,在SYSTEM的连接中,执行
DROP USER CC;
成功吗?为什么?
怎样才能成功删除用户CC ? 仅仅断开连接就行了吗?
为何要加Cascade ?删去后,还能以用户CC的身份连接吗?
15、在SYSTEM的连接中,重新创建用户CC和DD:查看这两个用户的权限
16、以CC和DD的身份分别建立连接,使得目前系统加上原来的SYSTEM共有三个连接(为识别方便,连接名和用户名一致)
选择CC连接,执行:
Create Table from_CC(内容 char(1));
Insert into from_cc values(‘a’);
select * from from_cc;
选择DD连接,执行:
select owner, table_name from all_tables where table_name=‘FROM_CC’;
显示什么?什么意思?
select * from from_cc;
显示什么?什么意思?
选择CC连接,执行:
grant all on from_cc to dd;
选择DD连接,执行:
select owner, table_name from all_tables where table_name=‘FROM_CC’;
显示什么?什么意思?
select * from from_cc;
显示什么?
select * from cc.from_cc;
显示什么?怎么回事?
刷新DD连接下的表,有没有“FROM_CC”这个表?
选择DD连接,执行:
Insert into cc.from_cc values(‘d’);
select * from cc.from_cc;
插入成功了吗?
17、选择CC连接,执行:
Revoke insert on FROM_CC from DD;
选择DD连接,执行:
select * from cc.from_cc;
能显示表的内容吗?
Insert into cc.from_cc values(‘y’);
select * from cc.from_cc;
插入成功了吗?
选择SYSTEM连接,执行:
Revoke dba, resource from DD;
选择DD连接,执行:
select * from cc.from_cc;
能显示表的内容吗?
Insert into cc.from_cc values(‘z’);
select * from cc.from_cc;
插入成功了吗?
选择CC连接,执行:
Revoke all on FROM_CC from DD;
select * from cc.from_cc;
选择DD连接,执行:
select * from cc.from_cc;
18、删除连接DD后,重新添加连接DD
select * from cc.from_cc;
select * from user_role_privs;
当前用户有多少种权限?
Create Table from_DD(哦 char(2));
能执行吗?
选择SYSTEM连接,执行:
grant resource to dd;
选择DD连接,执行:
Create Table from_DD(哦 char(2));
能执行吗?
删除连接DD后,重新添加连接DD
Create Table from_DD(哦 char(2));
Insert into from_dd values(‘甲’);
select * from from_dd;
能看到记录“甲”吗?
选择CC连接,执行:
select * from dd.from_dd;
能看到记录“甲”吗?
用户CC怎样才能看到from_dd表的所有记录?用户CC怎样才能为from_dd表添加记录?
19、创建新的用户并授权:
20、以用户CC的身份建立连接,并在此连接下执行后面的操作;
21、拷贝代码运行,建立表格及输入数据:
表中共有多少行数据?
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的作用是什么?
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;
运行结果显示,Savepoint的作用是什么?
五、实验结果及分析
1、以用户CC的身份建立连接,并在此连接下执行后面的操作;
select * from user_role_privs;
可以看到自己的权限,有多少种权限?
有三种权限,分别是CONNECT、DBA、RESOURCE
2、在CC连接中:拷贝代码运行,删去旧的同名数据表(如果是新创建的用户,此步骤可以省略):
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;
3、在CC连接中:拷贝代码运行,建立表格及输入数据:
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’);
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);
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’);
4、在CC连接中:确认orcl数据库中有这三个数据表,以及相应的数据
select * from all_tables where owner=‘CC’;
依次执行下列语句:
select * from reader;
select * from book;
select * from rb;
5、在CC连接中:查询用户CC的权限信息(每句单独执行):
select * from dba_role_privs;
select * from dba_sys_privs;
select * from role_sys_privs;
第一条语句:
第二条语句:unlimited tablespace无限制的表空间权限
第三条语句:列出了很多角色的权限
6、在CC连接中:查询用户创建的表
select table_name from user_tables;
7、在CC连接中:删去数据表BR,成功吗?
成功了,显示表已删去
再次执行:
select table_name from user_tables;
显示什么结果?
查询结果只有reader表和book表了。
8、回收用户CC的部分权限:以SYSTEM的身份连接(可以在SQL DEVELOPER的右上角切换),在此连接中执行
Revoke dba, resource from CC;
再用select * from user_role_privs;查cc的权限,只剩下CONNECT了
9、以CC的身份连接数据库(可以在SQL DEVELOPER的右上角选择连接),执行:Create Table Aa(cola int);
成功吗?为什么?
执行失败,因为上一步已经回收了cc的DBA和resource权限,cc已经无权限创建表格了。
10、切换为SYSTEM的连接,执行切换为SYSTEM的连接,执行
grant resource to CC;
11、切换为CC的连接,执行
select * from user_role_privs;
可以看到自己的权限,有多少种权限?
有两种权限,CONNECT,RESOURCE
Create Table Aa(cola int);
成功吗?为什么?
成功了,因为system用户把resource权限授予了cc,所以cc有创建表的权限
12、切换为SYSTEM的连接,执行
DROP USER CC;
成功吗?为什么?
失败了,因为还没有断开连接。
13、删除连接CC,在SYSTEM的连接中,执行
DROP USER CC;
成功吗?为什么?
失败了,必须指定 CASCADE 以删除 ‘CC’
怎样才能成功删除用户CC ? 仅仅断开连接就行了吗?
仅仅断开连接不行,还需要指定CASCADE。
语句为 DROP USER CC CASCADE;
为何要加Cascade ?删去后,还能以用户CC的身份连接吗?
因为用户cc创建了一些基本表,在不先删除基本表的前提下想要删除用户cc,要cascade级联才能删除成功。
删去后,不能以cc身份连接。如图:
14、在SYSTEM的连接中,重新创建用户CC和DD:查看这两个用户的权限
Create User Cc Identified By Ccpassword;
Create User dd identified by ddpassword;
grant resource, connect, DBA to cc,dd;
查看这两个用户的权限(只有SYSTEM才有权执行下面这条语句):
select * from dba_role_privs where GRANTEE in (‘CC’,‘DD’);
15、以CC和DD的身份分别建立连接,使得目前系统加上原来的SYSTEM共有三个连接(为识别方便,连接名和用户名一致)
选择CC连接,执行:
Create Table from_CC(内容 char(1));
Insert into from_cc values(‘a’);
select * from from_cc;
选择DD连接,执行:
select owner, table_name from all_tables where table_name=‘FROM_CC’;
显示什么?什么意思?
查询表名为FROM_CC的表的创建者owner和表名table_name。
select * from from_cc;
显示什么?什么意思?
在用户dd中无法查询到表from_cc的数据信息。因为表from_cc在用户cc中创建的,且用户cc并未授权给用户dd。
选择CC连接,执行:
grant all on from_cc to dd;
选择DD连接,执行:
select owner, table_name from all_tables where table_name=‘FROM_CC’;
显示什么?什么意思?
查询表名为FROM_CC的表的创建者owner和表名table_name。
select * from from_cc;
显示什么?
select * from cc.from_cc;
显示什么?怎么回事?
虽然用户cc把对from_cc表的all操作权限授予用户dd了,但这个表终究还是
用户cc创建的,所以,想要在用户dd中查询from_cc表的数据,则要指明from_cc的创建用户。
刷新DD连接下的表,有没有“FROM_CC”这个表?
没有这个表,用户dd只是获得了对表from_cc的all权限,但其连接下的表并不会有from_cc。
选择DD连接,执行:
Insert into cc.from_cc values(‘d’);
select * from cc.from_cc;
插入成功了吗?
看起来是成功了,但去用户cc执行select * from from_cc;发现没有该数据
此处没有commit;提交插入的数据,所以在用户cc中查询表from_cc的数据时不会显示’d’的。
16、选择CC连接,执行:
Revoke insert on FROM_CC from DD;
选择DD连接,执行:
select * from cc.from_cc;
能显示表的内容吗?
可以。
Insert into cc.from_cc values(‘y’);
select * from cc.from_cc;
插入成功了吗?
看起来是成功了,实际上dd应该没有插入数据的权限
选择SYSTEM连接,执行:
Revoke dba, resource from DD;
选择DD连接,执行:
select * from cc.from_cc;
能显示表的内容吗?
可以显示。
Insert into cc.from_cc values(‘z’);
select * from cc.from_cc;
插入成功了吗?
看起来成功了,实际上dd没有插入数据的权限
选择CC连接,执行:
Revoke all on FROM_CC from DD;
select * from cc.from_cc;
选择DD连接,执行:
select * from cc.from_cc;
17、删除连接DD后,重新添加连接DD
select * from cc.from_cc;
显示表不存在
select * from user_role_privs;
当前用户有多少种权限?
只有一种权限,CONNECT
Create Table from_DD(哦 char(2));
能执行吗?
不能,dd现在没有建表的权限
选择SYSTEM连接,执行:
grant resource to dd;
选择DD连接,执行:
Create Table from_DD(哦 char(2));
能执行吗?
不能,仍然显示权限不足
删除连接DD后,重新添加连接DD
Create Table from_DD(哦 char(2));
Insert into from_dd values(‘甲’);
select * from from_dd;
能看到记录“甲”吗?
可以看到记录“甲”了
选择CC连接,执行:
select * from dd.from_dd;
能看到记录“甲”吗?
不能,只能看到一个空表
用户CC怎样才能看到from_dd表的所有记录?用户CC怎样才能为from_dd表添加记录?
在dd连接中执行语句grant all on from_dd to cc;授予cc所有权限
再在cc连接中执行语句select * from dd.from_dd;
这样就可以看到from__dd表的所有记录了。
在用户cc中执行语句:insert into dd.from_dd values(‘乙’);
再执行commit;就可以提交插入的数据,这样cc就可以为from__dd表添加数据了。
18、创建新的用户并授权:
create user cc1 identified by ccpassword ;
grant resource, connect, DBA to cc1;
19、以用户CC的身份建立连接,并在此连接下执行后面的操作;
create table mytable(tno char(2) primary key, tname char(8));
20、拷贝代码运行,建立表格及输入数据:
Insert Into Mytable Values(‘01’,‘赵老大’);
select * from mytable;
Insert Into Mytable Values(‘02’,‘赵老二’);
select * from mytable;
Insert Into Mytable Values(‘03’,‘赵老三’);
select * from mytable;
表中共有多少行数据?
表中共有三行数据
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处,表中剩下三行数据,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;
运行结果显示,Savepoint的作用是什么?
保存点(savepoint)是事务过程中的一个逻辑点,用于取消部分事务,当结束事务时,会自动的删除该事务中所定义的所有保存点。当执行rollback时,通过指定保存点可以回退到指定的点。
六、实验心得体会
在实验中,我发现一些权限的授予和收回操作,需要断开目标用户的连接,再重连才能生效。通过这次实验,我掌握了数据库的权限控制方法,对语句间的逻辑也有了更深的认识,对数据库的认识也有了很大的进步。
实验2-2
Oracle数据库对象
一、实验目的
Oracle 数据库包含许多数据库对象,例如表、视图、索引、序列、存储过程、触发器等。表、视图、索引的操作在前面的实验中已经做了相应的练习,本实验将介绍如何使用序列、触发器和存储过程。同学们可以通过本实验掌握如何定义、使用删除这些数据库对象。
二、实验原理
PL/SQL 块结构说明
(1)声明部分 主要用于声明变量、常量、数据类型、游标、异常处理名称以及本地(局部)子程序定 义等。
(2)可执行部分 执行部分是 PL/SQL 块的功能实现部分。该部分通过变量赋值、流程控制、数据查询、 数据操纵、数据定义、事务控制、游标处理等实现块的功能。
(3)异常处理部分 异常处理部分用于处理该块执行过程中产生的异常。
三、使用仪器、材料
Oracle 19c,windows10;
四、实验内容
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’;
显示有多少行?
有450行。
select object_name,owner from all_objects where owner = ‘CC’;
显示有多少行?
0行。
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’;
显示有多少行?
两行。
select object_name,Object_Type, owner from all_objects where owner = ‘SYSTEM’ and OBJECT_TYPE=‘SEQUENCE’;
显示有多少行?
7行。
Select Object_Name, Object_Type, Owner From All_Objects Where Owner = ‘CC’ and OBJECT_TYPE=‘SEQUENCE’;
显示有多少行?
两行。
select my_seq_01.nextval from dual;
重复执行上面的这条语句,得到什么序列?
结果是下图中的nextval列中数字从1开始,每执行一次语句就增加1。序列是1,2,3,4,5,6,7,8,9,10,11,12,…
alter sequence my_seq_01 increment by 10 ;
select my_seq_01.nextval from dual;
重复执行上面的这条语句,得到什么序列?
结果是下图中的nextval列中数字从上次的9开始,每执行一次语句就增加10。序列是19,29,39…
select my_seq_02.nextval from dual;
重复执行上面的这条语句,得到什么序列?
结果是下图中的nextval列中数字从1开始,每执行一次就增加2。序列是1,3,5,7,9…
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;
重复执行上面的这条语句,得到什么序列?
结果是下图中的nextval列中数字从100开始,每执行一次就增加3。序列是100,103,106,109,112,115…
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));
成功了吗?上面的三个表的创建顺序能否任意调整?
成功了。前面两个表student和course的创建顺序可以任意调整,但sc表必须第三个创建,因为sc表的rno和cno属性参照的分别是student表的rno属性和course表的cno属性。
select object_name, Object_Type, owner from all_objects where owner = ‘CC’;
显示有多少行?索引是怎么产生的?
有8行。为了避免对基本表进行全表扫描,关系数据库管理系统一般都在主码上自动建立一个索引。
到SOL DEVELOPER的可视化窗口查看student表的索引信息:
查看SC表的索引,有哪些列来确定?依据是什么?索引名是什么?
由sno、cno列来确定,依据是主码,索引名是SYS_C007552
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;
查看student表的内容
insert into course values (105,‘程序设计’);
insert into course values (908,‘大学英语’);
insert into course values (433,‘数据结构’);
commit;
select * from course;
查看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’;
显示有多少行? 1行。
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;
显示结果说明,成绩为负数的话,在数据表里是什么内容?存储过程有什么好处?
成绩为负数的话,在数据表里显示的是空值(null)。
好处:1、存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2、存储过程可以重复使用,可减少数据库开发人员的工作量。
分数为0,和分数为负数,有区别吗?
有区别。分数为0的时候,grade属性显示的是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;
看到和上一步的显示结果有何区别?
增加了一列,根据分数划分成A、B、C、D四个等级。
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表每一行之前先创建或更新触发器trigger_ins,然后就是根据要插入的分数得到对应的A或B或C或D,即gradelevel列的值。然后再插入数据,查询数据时会发现gradelevel列的值就是分数对应的字母了。
二、触发器影响其他表:
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;
触发器生成成功了吗?当前触发器的目录下有多少项?
生成成功了。触发器目录下有两项:COURESE_INS和SC_INS
select * from course;
记下当前各科的最高分数
所有最高分数都为0,因为上面步骤执行了update course set maxgrade=0;
把maxgrade属性列的值全部设置为0。
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号课程的分数是多少?级别是什么?
分数是64分,级别为C。
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)有没有变化?
一个修改语句,可以同时触发两个表的数据改变吗?
修改成功了,级别变化成A,程序设计的最高分变成了100。由上分析可得:一个修改语句可以同时出发两个表的数据改变。
六、实验心得和体会
通过这次实验,掌握数据库对象如触发器、存储过程和函数的定义和基本使用方法。
实验2-3
数据备份与恢复
一、实验目的
掌握ORACLE数据库系统的一种备份/恢复方法。
二、实验原理
Oracle数据库有三种标准的备份方法:
导出/导入
热备份(被备份的数据库不必关闭)
冷备份(被备份的数据库必须关闭)
导出备件是一种逻辑备份,冷备份和热备份是物理备份。
该实验做的属于逻辑备份。物理备份是指文件级的备份。
三、使用仪器、材料
Oracle 19c,windows10;
四、实验步骤
1、 以用户CC的身份建立连接,并在此连接下执行后面的操作。
2、 拷贝代码运行,删去旧的同名数据表。
3、 拷贝代码运行,建立表格及输入数据。
4、 以CC的身份连接,确认orcl数据库中有这三个数据表,以及相应的数据。
5、 打开“Database Configuration Assistant”,创建数据库mydb。
6、将数据库连接cc导出到D盘。
7、 确认D盘有文件“export from orcl.sql”。
8、 到ORACLE SQL DEVELOPER中以SYSTEM用户的身份建立新的连接(这个密码是前面自己新建数据库输入的密码)。
9、 在该连接下执行以下语句,即在数据库MYDB里增加用户CC,以便与备份的用户名一致(打开文件“export from orcl.sql”可见里面的语句带了用户名):
10、以用户CC的身份建立新的连接到数据库mydb:
11、 确认mydb中没有数据表READER、BOOK、RB:
12、在MYDB的CC用户连接中打开文件(或用记事本打开再复制粘贴)运行
13、确认MYDB中含有这三个表,且表的内容、约束等与数据库ORCL中的一致
14、为避免占用太多的系统资源,删去数据库MYDB。先删去有关MYDB的所有连接
15、打开“Database Configuration Assistant”
16、删去数据库MYDB:
注意:如果未删除数据库的连接,则无法删除数据库。
五、实验结果及分析
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;
3、 拷贝代码运行,建立表格及输入数据:
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’);
4、 以CC的身份连接,确认orcl数据库中有这三个数据表,以及相应的数据
select * from all_tables where owner=‘CC’ ;
select * from reader;
select * from book;
select * from rb;
5、 打开“Database Configuration Assistant”,创建数据库mydb
6、将数据库连接cc导出到D盘
7、 确认D盘有文件“export from orcl.sql”
export from orcl.sql 已在D盘中
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中的一致
mydb中含有这三个表,且表的内容、约束等与数据库ORCL中的一致
BOOK
READER
RB
14、为避免占用太多的系统资源,删去数据库MYDB。先删去有关MYDB的所有连接
删去 ccmydb 连接
删去mydbsys连接
15、打开“Database Configuration Assistant”
16、删去数据库MYDB:
注意:如果未删除数据库的连接,则无法删除数据库。
六、实验心得和体会
通过这次实验,对ORACLE数据库系统逻辑备份和恢复的方法有了初步的了解,更好的理解了数据库的知识,还了解到不能直接删除正在连接的用户,需要断开连接才能删除。数据库的备份和恢复是一项很重要的工作,还需多加练习使得操作更加熟练。
步骤繁琐,图片太多,我这里只有步骤和代码,请大家谅解一下