oracle中表空间管理,游标

≡放荡痞女 提交于 2020-04-05 19:58:59

一、表空间

oracle使用表空间来管理数据库的对象(表,序列,过程,函数,游标等)。

oracle的逻辑结构(看不见的):oracle数据库 =》 表空间 =》 表 序列  过程等对象。

oracle的物理结构(能看见):oracle 数据库 =》oracle的数据文件=》数据段=》数据区间=》数据块 。

oracle的数据文件分三种:

1、控制文件,以ctl结尾,控制文件中存储oracle运行所需要的字典,用户等对象。

2、日志文件,以log存储oracle操作产生的日志文件,还包含oracle的重做日志。

3、数据文件,存储用户或者系统创建的对象

 

表空间也是对象,需要存储到数据文件中,所以创建表空间的时候需要指定使用哪个数据文件。

创建表空间的语法:

create tablespace 表空间名称

datafile '存储的位置\文件名.dbf'  指定表空间使用的数据文件,如果文件不存在会自动创建

size 50m 表空间的初始大小

autoextend on next 30m 表空间如果空间不够用了,下次自动扩展的大小

maxsize  300m指定表空间的最大存储空间;

 

例子:

1 -- 创建表空间
2 create tablespace tab_test01
3 --指定使用的数据文件
4 datafile 'D:\test_tab\test01.dbf'
5 --指定表空间的初始大小
6 size 50m
7 --当表空间不够用时,下次自动增长的大autoextend on next 30m
8 --表空间自动增长的最大值
9 maxsize 300m;
1 -- 创建表空间
2 create tablespace tab_test02
3 --指定使用的数据文件
4 datafile 'D:\test_tab\test02.dbf'
5 --指定表空间的初始大小
6 size 50m;

表空间用到的物理文件,不要在磁盘上直接删除,否则数据库将不能正常启动,如果要删除数据文件,需要先删除表空间:

1 drop tablespace tab_test02;

oracle中有内置的默认的表空间:

1、TEMP01.DBF 临时表空间,存储oracle数据库运行产生的临时数据

2、UNDOTBS01.DNF重做表空间,存储数据库产生的重做文件。

3、USERS01.DBF用户表空间,存储默认用户的数据。当创建用户且用户不指定默认表空间的时候会使用该表空间。

 

二、用户管理

oracle中有三个重要用户 sys  system  scott,我们也可以自己创建用户

创建用户的命令:

1 create user 用户名 identified by 用户密码 default  tablespace 表空间名称;

注意:创建用户的时候可以不指定默认表空间,如果不指定会使用系统的USERS的表空间

例子:

1 --创建用户 并指定使用tab_test01表空create user zhangsan identified by 123456
2 default tablespace tab_test01;
3 -- 创建用户,不指定默认表空间
4 create user lisi identified by 123456;

删除用户:

1 -- 指定cascade代表把用户和用户下的对象都一起删除。
2 drop user 用户名 [cascade];

修改用户密码:

1 alter user zhangsan  identified  by 123456;

connect连接数据库的角色,可以执行数据库的增删改查,但是不能执行数据库表的增删改,一般在开发环境中给用户赋予这种角色

resource开发者角色,可以执行数据库对象的增删改查,我们一般在开发中使用这种角色。

dba 数据库管理员角色,最高权限,可以执行数据库的任何操作,一般不建议使用这种角色。

给用户赋予角色可以使用如下语句:

grant 角色名1,角色名2... to 用户;

例子:

1 --为张三用户赋予连接的权限
2 grant connect to zhangsan;
3 --为张三赋予开发权限
4 grant resource to zhangsan;
5 --为张三同时赋予连接和开发权grant connect ,resource to zhangsan;

 

撤销权限可以使用以下语句:

1 --撤销张三的开发权限
2 revoke resource from zhangsan;

 

三、游标

1、游标的概念:游标是数据库中可以操作的一块内存区,可以方便的帮我们从数据库中获取数据,一般使用游标来遍历数据。

使用游标的语法:

 1 declare
 2 -- 声明游标变量
 3 cursor 游标变量名称 is sql语句;
 4 begin
 5 -- 打开游标
 6 open  游标变量名称;
 7 loop
 8 -- 从游标中获取数据
 9 fetch  游标变量名称  into rowtype 类型变量/record类型变量;
10 -- 判断是否从游标中获取到了数据,如果没有获取到数据,应该跳出循环
11 if 游标变量%农田found then
12 exit;
13 end if;
14 语句块;
15 end loop;
16 --关闭游标
17 close 游标变量名称;
18 end;

例子:输出部门表的所有数据

 1 --输出部门表的所有数据
 2 declare
 3 --声明游标变量
 4 cursor cur_dept is select * from dept;
 5 --声明行类型变量,用来接收游标获取到的数据
 6 v_dept dept%rowtype;begin
 7 --打开游标
 8 open cur_dept;
 9 loop
10 --从游标中获取数据
11 fetch cur_dept into v_dept;
12 -- 判断是否从游标中获取到了数据,如果没有获取数据跳出循环
13 --if cur_dept%notfound then
14 -- exit;
15 --end if;
16 --if 可以简写成如下形成
17 exit when cur_dept%notfound;
18 --打印数据
19 dbms_output.put_line('第'||cur_dept%rowcount||'行,部门编号:'||v_dept.deptno||',部门名称:'||v_dept.dname);
20 end loop;
21 --关闭游标
22 close cur_dept;
23 end;

可以使用游标名称%属性名称 来访问游标的属性 ,游标常用的有四个属性:

属性值

说明

isopen 判断游标是否已经打开
found 判断游标是否取到了数据,如果获取到了数据返回真,否则返回假
notfound 判断游标是否获取到了数据,如果获取到了数据返回假,否则返回真
rowcount 返回当前游标获取到的数据的行号

2、游标可以分为显示游标和隐含游标两种类型

显示游标

使用游标的时候可以给游标定义参数,这样游标就可以传不同的参数多次使用了

举例:写一个游标,根据部门编号,打印该部门下员工的信息

 1 declare
 2 --声明游标变量 ,加入参数
 3 cursor cur_emp(v_deptno number) is select * from emp where deptno=v_deptno;
 4 v_emp emp%rowtype;
 5 begin
 6 --打印部门编号为10的员工的信息
 7 --打开游标
 8 open cur_emp(10);
 9 loopfetch cur_emp into v_emp;
10 exit when cur_emp%notfound;
11 dbms_output.put_line('员工编号:'||v_emp.empno||',员工姓名:'||v_emp.ename);
12 end loop;
13 --关闭游标
14 close cur_emp;
15 dbms_output.put_line('======');
16 --打印部门编号为20的员工的信息
17 --打开游标
18 open cur_emp(20);
19 loop
20 fetch cur_emp into v_emp;
21 exit when cur_emp%notfound;
22 dbms_output.put_line('员工编号:'||v_emp.empno||',员工姓名:'||v_emp.ename);
23 end loop;
24 --关闭游标
25 close cur_emp;
26 end;

我们也可以一次性取出游标的所有数据,放入到table类型变量中:

 1 declare
 2 --声明游标变量 ,加入参数
 3 cursor cur_emp(v_deptno number) is select * from emp where deptno=v_deptno;
 4 --声明table类型
 5 type emp_table_type is table of emp%rowtype
 6 index by binary_integer;
 7 -- 声明table类型变量
 8 v_emp emp_table_type;
 9 begin
10 --打印部门编号为10的员工的信息
11 --打开游标
12 open cur_emp(10);
13 --一次性取出游标中的所有数据 ,放入table类型变量中
14 fetch cur_emp bulk collect into v_emp--关闭游标
15 close cur_emp;
16 --循环输出table类型变量中的内容
17 for v_i in v_emp.first .. v_emp.lasloop
18 dbms_output.put_line('员工编号:'||v_emp(v_i).empno||',员工姓名:'||v_emp(v_i).ename);
19 end loop;
20 end;

 

游标for循环

每次使用游标都需要打开和关闭游标,比较麻烦,我们可以使用游标for循环来简化游标的使用方式。

例子:打印部门表所有的内容

 1 declare
 2 -- 声明游标变量
 3 cursor cur_dept is select * from dept;
 4 begin
 5 -- 使用游标for循环不需要显式的打开或者关闭游标
 6 -- 循环变量也不需要显式声明,该游标变量是行类型rowtype类型或者记录类型record
 7 for v_dept in cur_dept
 8 loop
 9 dbms_output.put_line('部门编号:'||v_dept.deptno||',部门名称:'||v_dept.dname);
10 end loop;
11 end;

游标for循环可以继续简写:

1 begin
2 -- 游标for循环简写
3 for v_dept in (select * from dept)
4 loop
5 dbms_output.put_line('部门编号:'||v_dept.deptno||',部门名称:'||v_dept.dname);
6 end loop;
7 end;

注意:in后面一定加上小括号

游标变量类型

以前的游标没有办法从不同的表中取数据,在大项目中,有可能需要声明很多游标变量,非常繁琐,我们可以使用游标变量类型来解决这个问题

例子:声明游标变量类型,先从打印员工表数据,再打印部门表数据。

 1 declare
 2 --声明游标变量类型
 3 type cur_test_type is ref cursor;
 4 -- 声明cur_test_type类型的游标变量
 5 cur_test cur_test_type;
 6 v_emp emp%rowtype;
 7 v_dept dept%rowtype;
 8 begin
 9 -- 先打印员工表所有数据
10 --打开游标,同时告诉该从哪个表取数据
11 open cur_test for select * from emp;
12 loop
13 fetch cur_test into v_emp;exit when cur_test%notfound;
14 dbms_output.put_line('员工编号:'||v_emp.empno||',员工姓名:'||v_emp.ename);
15 end loop;
16 --关闭游标
17 close cur_test;
18 --再使用cur_test游标变量从部门表取数据
19 open cur_test for select * from dept;
20 loop
21 fetch cur_test into v_dept;
22 exit when cur_test%notfound;
23 dbms_output.put_line('部门编号:'||v_dept.deptno||',员工姓名:'||v_dept.dname);
24 end loop;
25 --关闭游标
26 close cur_test;
27 end;

隐含游标

oracle中也有隐含游标,在所有增删改语句执行之后,数据库会默认我们创建一个隐含游标,名字叫sql,我们可以访问隐含游标的属性,隐含游标不需要打开或者 关闭。

例子:删除员工,如果员工编号不存在,打印错误信息

1 begin
2 delete from emp where empno=9999;
3 --通过隐含游标判断是否删除成功
4 if sql%found then
5 dbms_output.put_line('删除成功');
6 else
7 dbms_output.put_line('删除失败'); 
8 end if;
9 end;

 

四、面试题

1、oracle中有几种内置角色

connect  resource dba

2、游标的四个属性是什么

isopen  found  notfound  rowcount

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!