dba_data_files
可以查询到oracle实例下的三种内存
一个逻辑机构可以对应多个物理结构,而一个物理结构只能对应一个逻辑结构
在oracle中创建用户需要指定密码
default tablespace
默认表空间 如果没有指定 用户都是users
temporary tablespace
临时表空间
刚创建的用户不能连接数据库,因此需要通过管理员给予用户连接和资源的权限。
grant connect,resource to xxx(user);
要想查看其它用户的表等信息,需要得到别人给自己的授权
给予权限
grant xx to user [with grant option 使用允许授权的用户再次将权限给予他人]
账号的锁定和解锁
alter user xxx account lock;
alter user xxx account unlock;
修改密码
alter user xxx identified xxx;
删除用户
drop user xxx
drop user xxx [cascade 删除用户和与用户有关的一切]
connect
临时用户,特别是不需要建表的用户,赋予connect,(可以创建和访问自己的表,但无法操作和访问其他人的表。)该角色可以创建表,视图,索引,序列,簇,同义词,会话
resource
与connect很类似,但不是临时用户
dba
管理员
拥有授权权限
撤销授权
查看当前用户的所有角色
select * from user_role_privs;
查看角色的权限
select * from role_sys_privs
select * from role_sys_privs where role="connect"
查看从别人获得的 与 自己给别人的权限
select * from user_tab_privs;
意义:根据用户的情况,分配不同的表空间和空间大小,起到限制的作用;表空间支持分区散列(把重要且频繁访问的东西放在可快速访问的区域中),可以 执行计划 存放索引。
表空间,系统默认的6中表空间
create tablespace xxxx datafile [硬盘上的路径] size xxM;
如果表空间满了,可以增加容量
alter tablespace xxx add datafile size xxM.
drop tablespace xxx including contents
drop tablespace xxx including contents and datafiles
create table table_name(...)
如果用户创建表的时候,没有指定表空间,那么放在用户default tablespace
中,默认是user。
如果用户有修改过自己的默认表空间,就不会将自己创建的表放在user中
在建表时复制数据
create table table_name AS select column_1,column_2 FROM table_old
在添加时复制(要求列的名和类型要一致)
insert into table_name[column] select column_1,.. from table_old
dual表是一张只有一个字段1个记录的空表,可用于调试
有char 和没nchar 的区别:有n表示使用字符计算,用unicode来存储
如果按照字节来计算的话 GBK汉字是2个字节,而utf-8是3~4个字节
char2和char的区别,带2表示是oracle优化器对于空格会做出优化,压缩空间存储。
database–>tablespace,index .. –>segment(段) –> extent(区间)包含了许多的data block;
not null:null 与 ” 都是不允许的
unique 唯一性约束,可以是单列或者是多列 允许多个null
primary key 主键约束 可以是单列或者多列
foreign key 外键约束 在参照关系中的值必须在被参照关系中对应字段的域范围内。
check 数据插入或者更新时触发的约束。
查询约束名字典表
select constraint_name from user_constraints [where constraint_name = '']
修改约束名
alter table userinfo rename constraint_old to constraint_new
创建表时设置外键
create table table_name (
column_name datatype references table2(column_name)
)
从表的外键不一定要和主表的主键名称相同,只要数据类型完全一样即可。
oracle 5 大约束中只有not null 没有表级约束
避免使用复合主键因为复合主键常常带来信息的困惑,比如姓名,班级,手机号作为一个复合主键,
姓名 | 班级 | 电话 |
---|---|---|
张文 | A | 1333 |
李四 | B | 1444 |
张文 | A | 1433 |
这个时候,当我们对表执行的查询中并没有带上班级,执行select * from student
得到了一个班级的2个张三,他们除了电话号码不同外,其他相同。对于这个信息,可以有2种理解
1,张文是同一个人,具有2个电话
2,张文不是同一个人,只有1个电话。
因为复合主键只有所有的属性相同才会被认为是重复的,因此尽可能的不要使用复合主键。
oracle只能增加约束或删除,而无法修改约束
约束一定要在插入数据前就都制定好!!!而不要等存在数据时再去做修改
alter table table_name drop constraints c_name;
alter table table_name add constraints c_name
check ( ) 约束内容,有多个就用and链接 或者 or
check ( name > 5) 即便name是一个字符型,但在oracle中,check约束使得他变为了数字型,因而一直插入时会出现数字不符的情况。
check (length(name) >5 ) 表示name字符数要大于5 这是正确的表达。 length() 是oracle中的函数。
create index index_name on table_name(字段)
普通索引,允许输入重复的值
create unique index index_name on table_name(字段)
唯一索引和unique很像,除了null允许多次外,不允许重复。
唯一约束和唯一索引区别
1.约束是来检查数据的准确性,索引是来实现数据查询的优化,目的不同
2.创建唯一约束会在oracle中创建一个约束也会创建一个唯一索引
3.创建唯一索引只会创建唯一索引,不会创建唯一约束
当索引失效时,需要重建索引
alter index index_name rebuild
在oracle中,可以在要执行语句上,按f5查看预定执行计划,观察索引是否失效。
组合索引
当两个或多个列经常一起出现在where条件中时,则在这些列上同时创建组合索引
位图索引
列中有非常多的重复的值时候。例如某列保存了 “性别”信息。
Where 条件中包含了很多OR操作符。
较少的update操作,因为要相应的跟新所有的bitmap
优点:位图以一种压缩格式存放,因此占用的磁盘空间比标准索引要小得多
视图是一种逻辑结构,本身并不存储数据表中的信息。一般我们可以对于复杂且经常要访问的查询去建立视图,这样可以达到一个简便的目的。同时,一张数据表中的所有信息未必允许用户看的,例如职工表,职工的基本信息可能是不具有特殊性(姓名,性别,出生,职位),是可以随便谁看的,但如果涉及到私密的信息(薪水,电话等等),那么并不是所有人都有权利去看的。
使用视图就是可以建立一个逻辑关系,里面只看包了你想要别人看到的东西,简而言之,就是视图是可以完全或者部分包含单张或多张表的信息。
创建视图的一般语法如下:
/*视图不指定属性则默认是查询结果的所有字段*/
create view view_name(attr1,attr2...) as
select .. from table1,table2..;
一个创建好了的视图,同样的,也可以被用于去创建一个新的视图。
因为from后面跟随的,只能是table或view;
使用视图和使用普通的表是一样的。
视图对于查询而言,是一个很便捷的工具,但如果对于视图执行 更新 插入或删除,可能会带来严重的问题。
例如有2张表,学生表和老师表,学生表中的教师id作为外键,将学生表和老师表联系起来。我们创建了一个视图,显示了不同学生他们的教师名。现在我们想要去插入一条记录,包含一个不存在教师表的老师名,这个时候,插入操作就会出错,并作出如下提示
无法通过链接视图改变基表
因为绝大多数的数据不允许视图更新,只有在如下情况下视图是可更新的。
这样创建出来的是图是可更新的视图。
事务其实就是由查询或更新语句的序列(下一节的序列不一样)组成。例如
select * from table1;
update table1 set attr=xxx,attr2=value2 where id=xx;
insert into table1(attr1=xx) values(xx) where id=xy;
在一些可视化工具(如PL/SQL)的sql窗口,全选这3个,点击执行,那么就构成了一个事务。事务的重大意义就是当其中出现错误时(违反约束或者系统故障)时,会回滚到最初的状态,这样也就是保持状态。
事务使用的一个注意点
在事务中,如果事务结束前,执行过DDL(create table.. drop table.. 等等)语句,那么事务将无法回滚
在其他的一些数据库中,有auto increment来达到自增的目的,但是这个语法在oracle中不支持,解决的办法是创建一个序列对象。
创建序列对象的一般语法如下
create sequence sequence_name
start with xx
minvalue xx
maxvalue xx
increment by xx
cache xx (default 20)
cycle[nocycle]
如果没有修改cache,maxvalue-minvalue<20就会出错
使用方法,
seq_name.nextval 只要有使用过,不论是否更新或者插入成功失败,都会改变序列对象的值。
curval 当前值,如果没有执行过next,那么curval会出错
nextval 执行一个值,如果已经达到了最大值并且不循环的话,会出错
1.创建同义词语句:
create [public] synonym table_name for user.table_name;
其中第一个user_table
和第二个user_table
可以不一样。
此外如果要创建一个远程的数据库上的某张表的同义词,需要先创建一个Database Link(数据库连接)来扩展访问,然后在使用如下语句创建数据库同义词:create synonym table_name for table_name@DB_Link;
当然,你可能需要在user用户中给当前用户(user2)授权: grant select/delete/update on user2
2.删除同义词:drop public synonym table_name;
3.查看所有同义词:
select * from dba_synonyms
同义词拥有如下好处:
伪列 本身并不存在,但是可以进行使用的列,如sysdate,rowNum rowID
rowNum 行号 根据搜索的结果从1开始排列,不与关系中的元组号绑定。即rownum永远是从1开始排列,跟所查询的表格中的顺序无关。
rowNum一般用户获取第一条记录或者前N条记录,(可用于分页)
分页例如
–分页查询 找到51~59之间的sessionid记录(显示的就是51~59)
select r, SESSIONID from
(select rownum r,sys.AUD$.* from sys.AUD$ where rownum<60)
where r>50;
/*
当有这种情况事,外层的rownum不认识里层的rownum,依然是要从1开始,而此时指定的条件是从3开始,于是就得不到想要的结果
*/
select * from (select rownum, test_tbl.* from test_tbl where rownum<10) where rownum>3
delete不是完全的删除,在没有保存退出之前,他的索引,视图等还是保存着,占据硬盘空间。
truncate 截断表,清空表中所有的记录,连通索引 视图等都清除。
purge recycle 清空回收站
drop table table_name purge 删除表并清空回收站。
如果误删了,想找回,可以使用oracle的闪回技术
FLASHBACK TABLE table_name TO BEFORE DROP.
IN
在where中 如果有多个OR,且判断条件很相似 如 A=1 A=3 A=4 A=9 那么where将执行4次,判断,在性能效率上就比较低,此时就推荐使用IN
A in (1,3,4,9)
注意点,也可以是会用 NOT IN 表示不再范围内,但千万不要使用 NOT IN (null)!!
not in 查找的范围中如果有null,那么将不会有任何结果返回,in 无此限制。
HAVING 必须要和GROUP BY 结合用,WHERE 不能使用统计函数。
下面是3中子查询的建议
HAVING 子查询需要返回单行单列,而且需要用统计函数进行过滤
WHERE 子查询可以是单行单列 单行多列 多行单列
多行单列相当于得到的是一种范围 可以结合 IN, ANY, ALL来进行范围筛选。
如果子查询有行返回,则返回true,没有就是false,exists关心的行数据,而in是列的数据,因此exists性能比in更好一些。
exists 和 in 比较
exists 是先执行主查询 然后 执行子查询,子查询存在一条记录,那么便返回主查询的结果。
in 先是将主查询挂起,先执行子查询,然后执行主查询,判断主查询结果是否在子查询的范围内。
分组聚集,类似去重显示,同时可以对分组的属性使用聚集。
例如
select deptno,job,max(sal) from emp group by deptno,job
找出每个部门不同职业的最高薪水。
GROUP BY 分组聚集一个很重要的条件
保证出现在select语句中 但没有被聚集的属性 只能出现在group by 中。换句话说,出现在select中的属性,要么在聚集函数中,要么在group by中。
例如下面的查询是错误的
select dept_name, id, avg(salary) //id 没有出现在聚集函数或者group by语句中
from instructor
group by dept_name
Join 中 Using的用法
select * from empl join deptm using(deptno);
等价于
select * from empl e, join j where e.deptno=j.deptno;
select 中的属性要一样,不一致会出现列数不一致的信息
union 默认是不包含重复的,union保留所有的
(select deptno from emp) union all (select deptno from dept)
在ORACLE写代码,
PL/SQL procedural Language /SQL :是在ORACLE 标准的SQL之上扩展的语言,执行SQL语句,定义变量,给变量赋值,条件,循环,异常处理,游标
procedure 过程化语言
SQL> set serveroutput on
SQL> begin
2 dbms_output.put_line('hello world');
3 end;
4 /
定义变量
declare
---定义变量, 变量名 数据类型
v_name varchar(10);
begin
--赋值 :=
v_name:='20';
dbms_output.put_line('hello world ' || v_name);
end;
SQL> declare
2 v_name varchar(20);
3 begin
4 v_name:=&;
5 dbms_output.put_line('hello '||v_name);
6 end;
SQL> declare
2 v_name staff.staf_name%type;
3 begin
4 v_name:=&s; ‘&’表示输入赋值,字符串需要''
5 dbms_output.put_line('hello'||v_name);
6 end;
declare
v_emp staff%rowtype; 这将存入一行的所有字段的类型,放入多个信息
begin
select * into v_emp
from staff
where staf_id=2;
dbms_output.put_line(v_emp.staf_name);
end;
if elsif else结构
declare
sal number(3,0);
begin
sal:=#
if (sal<100) then
dbms_output.put_line('小于100');
elsif (sal<200) then
dbms_output.put_line('大于100 小于200');
else
dbms_output.put_line('大于200');
end if;
end;
loop循环
SQL> declare
2 i number:=1;
3 begin
4 loop
5 dbms_output.put_line(i);
6 i:=i+1;
7 exit when(i>5);
8 end loop;
9 end;
10 /
FOR循环
for arg in start..endnum loop
//execute body;
end loop;
异常的捕获
SQL> declare
2 v number:=0;
3 begin
4 v:=1/0;
5 exception
6 when others then
7 dbms_output.put_line('错误发生了');
8 end;
存储过程一般语法
create or replace prc_name(arg1 in type, arg2 out type)
is[as]
begin
// execute body;
end;
可以是无参,或仅带有输入 或输出 或多个的输入输出
create or replace procedure prc_test(p_balance in number)
is
begin
update bank set user_balance=p_balance where user_id=1;
commit;
end;
调用这个过程
declare
v number(12,0);
begin
v:=&n;
prc_test(v);
end;
create or replace procedure prc_test2(p_id in number, p_balance out number)
is
begin
select user_balance into p_balance from bank where user_id=p_id;
end;
调用这个过程
declare
b number(12,0);
v number(2,0);
begin
v:=&id;
prc_test2(v,b);
dbms_output.put_line(b);
end;
需要用到
CallableStatement
Connection con = JDBCTools.getConnection();
try {
//调用存储过程,使用prepareCall
CallableStatement cstmt = con.prepareCall("{call prc_test2(?,?) }");
cstmt.setInt(1, 1);
//第二个参数为out,需要使用registerOutParameter
cstmt.registerOutParameter(2, oracleTypes.INTEGER);
cstmt.execute();
//执行完毕,获取out的值
int i = cstmt.getInt(2);
System.out.println(i);
cstmt.close();
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
create or replace function fn(num1 number) return nvarchar2
is
v_name nvarchar2(10);
begin
select user_name into v_name from bank where user_id=num1;
return v_name;
end;
调用函数
select fn(1) as name from dual;