一、表空间
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: est_tab est01.dbf' 5 --指定表空间的初始大小 6 size 50m 7 --当表空间不够用时,下次自动增长的大autoextend on next 30m 8 --表空间自动增长的最大值 9 maxsize 300m;
1 -- 创建表空间 2 create tablespace tab_test02 3 --指定使用的数据文件 4 datafile 'D: est_tab est02.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