您的位置:首页 > 数据库 > Oracle

oracle数据库精炼核心技术

2017-01-01 16:54 375 查看

SQL(Structured Query Language)操作

Oracle的数据类型

表的基本管理(DDL:Data Definition Language)

表的增删改语句(insert,update,delete)(DML:Data Manipulation Language)

增删改的事务操作(DCL:Data Control Language)

表的查询语句基本结构(select)(DML:Data Manipulation Language)

基本查询

Oracle中的函数查询

分组查询

多表查询

子查询(重点掌握)

结果排序

集合运算

sql查询的综合案例(掌握,强化)

授权(DCL:Data Control Language)

视图(DDL:Data Definition Language)

索引(DDL:Data Definition Language)

序列(DDL:Data Definition Language)

同义词(DDL:Data Definition Language)

表的高级管理(DDL:Data Definition Language)

PowerDesigner的使用

数据库链路

闪回

Oracle的数据类型(了解)

CHAR    固定长度字符串     最大长度2000bytes    
VARCHAR2    可变长度的字符串,   最大长度4000bytes   可做索引的最大长度749
NCHAR   根据字符集而定的固定长度字符串     最大长度2000bytes    
NVARCHAR2   根据字符集而定的可变长度字符串     最大长度4000bytes    
DATE    日期(日-月-年)   DD-MM-YY(HH-MI-SS),经过严格测试,无千虫问题      
TIMESTAMP   日期(日-月-年)   DD-MM-YY(HH-MI-SS:FF3),经过严格测试,无千虫问题     与DATE相比较,TIMESTAMP有小数位秒信息
LONG    超长字符串   最大长度2G,足够存储大部头著作     
RAW     固定长度的二进制数据  最大长度2000bytes   可存放多媒体图象声音等
LONG RAW    可变长度的二进制数据  最大长度2G  可存放多媒体图象声音等
BLOB    二进制数据   最大长度4G   
CLOB    字符数据    最大长度4G   
NCLOB   根据字符集而定的字符数据    最大长度4G   
BFILE   存放在数据库外的二进制数据   最大长度4G   
NUMBER(P,S)     数字类型    P为整数位,S为小数位      
DECIMAL(P,S)    数字类型    P为整数位,S为小数位      
INTEGER     整数类型    小的整数     
FLOAT   浮点数类型   NUMBER(38),双精度   
REAL    实数类型    NUMBER(63),精度更高


表的基本管理(DDL:Data Definition Language)

DDL主要有以下关键字:
create,alter, drop,truncate

创建表
create table tname(c1 t1 default v,c2 t2,,);
如: create table student(id integer,name varchar2(10) default 'oracle');

create table tname as 子查询
如:
create table ttemp as select * from emp where 1=2;(不要数据)
create table ttemp as select * from emp;(要数据)
修改表
alter table tname add col type;--追加列
alter table tname modify col newtype;--修改类的类型
alter table tname drop column col; --删除列
alter table tname rename column cname to cnewname;--修改列名
rename tname to tnewname--修改表名

删除表
drop table tname; 把表放入回收站
Oracle的回收站:
select * fr
4000
om user_recyclebin; 查看回收站
purge recyclebin; 清空回收站
drop table tname purge; 回收站直接没有
select * from "回收站的表名";可以看到数据
flashback table tname to before drop;--恢复表(闪回)

销毁创建表
truncate table tname;把表删除重建

表的重构(去掉因删除造成的碎片)
alter table emp move;


表的增删改语句(insert,update,delete)(DML:Data Manipulation Language)

insert语句

指定列插入数据(列和值要对应)
insert into tname(c1,c2,,,) values(v1,v2,,,,)
如:insert into dept(deptno,dname) values(70,'oracle');

所有列插入数据
insert into tname values(v1,v2,,,,)
如:insert into dept values(80,'java','shenzhen');

通过子查询插入数据
insert into tname  select .. from tname2;
如:insert into ttemp  select * from emp;

update语句

update tname set c1=v1,c2=v2,,,where condition...
如: update dept set dname='c++' where deptno=80;

delete语句

delete from tname where condition....
如: delete from dept where deptno=80;

delete与truncate的区别:
1. delete逐条删除;truncate先摧毁表,再重建
2. delete是DML(可以回滚)  truncate是DDL(不可以回滚)
3. delete不会释放空间 truncate会
4. delete可以闪回(flashback,下面有介绍) truncate不可以
5. delete会产生碎片 truncate不会


增删改的事务操作

四大特点:
原子性(atomicity)
一致性(consistency)
隔离性(isolation)
持久性(durability)

1.起始标志:dml语句insert update delete
2.结束标志:
commit
显示提交
隐式:
正常退出
ddl (create ,drop ,alter,truncate等)
dcl(grant revoke等)
rollback
显示
隐式: 非正常退出,掉电,死机
回滚点:
savepoint a
rollback to savepoint a;

3.oracle自动解决死锁机制
如果发生死锁,oracle机制中会强制关掉一个事务。让发生死锁的其他事务继续执行。


表的查询语句基本结构(select)(DML:Data Manipulation Language)

select 语句:

select 列,函数,子查询
from 表1,表2,子查询 或者 from 表1 inner join 表2 on 条件.
where 条件,子查询
group by 分组列,函数
having 条件,子查询
order by 排序

下面是执行顺序:

(7)select (8)distinct
(1)from [left_table]
(3)<join_type> join <right_table>
(2)on <join_condition>
(4)where <where_condition>
(5)group by <group_by_list>
(6)having <having_condition>
(9)order by <order_by_list>


基本查询

1. show user;
当前用户
2. select * from tab;
用户下所有的表
3. 列的别名
col as "别名" (col as 别名)
col "别名" (原名显示)
cal 别名 (自动转大写,不能和oracle关键字冲突)
4. 数据字典
命令: select * from v$nls_parameters;
5. 修改日期格式
命令: alter session set NLS_DATE_FORMAT='yyyy-mm-dd';
6. between and
1. 含边界  2. 小值在前 大值在后
如: 查询薪资大于等于1000并且小于等于2000的员工信息
select * from emp where sal between 1000 and 2000;
7. 去掉重复行
distinct 去掉重复行(作用所有列)
如: select distinct deptno from emp;
8. concat("hello","world") 连接字符串  或者 ||
如: select concat('your name:',ename) from emp;
9. 模糊查询like 和转义字符 escape  (%零或多个,_一个)
如: 查询名字A打头的员工信息
select * from emp where ename like 'A%';
如: 查询名字第二个字母是L的员工信息
select * from emp where ename like '_L%';
如: 查询下名字带%的员工信息
select * from emp where ename like '%\%%' escape '\';
10. null条件查询 is null 或 is not null
如: select * from emp where COMM is null; 没有奖金的员工
11. desc 查看对象的定义信息
如:
desc dept; 查看表
desc procedure_name;查看存储过程


Oracle中的函数查询

基本格式:
select 函数名 from dual;

详情参考api文档。

1.数字函数

round(number,小数位数正负都行) 四舍五入
如: round(125.315) would return 125
trunc(number,小数位数) 截断
如: trunc(-125.815, 2) would return -125.81
如: trunc(125.815, -1) would return 120

2.字符函数

substr(a,b) 从a中,第b为开始
substr(a,b,c) 从a中,第b开始,取c个
length(a) 字符长度
lengthb(a) 字节长度
instr(a,b) 在a中查询b的位置
lpad(a,n,c) 左填充
rpad(a,n,c) 右填充
trim('H' from 'HsssH') 去掉前后指定的字符
replace('hello','l','*') 替换

3.日期函数
sysdate : 系统时间(格式),格式化显示时间,to_char(sysdate,'格式') 格式:yyyy-mm-dd hh24:mi:ss
systimestamp: 系统时间戳 :精度更高,格式化显示时间,to_char(sysdate,'格式') 格式:yyyy-mm-dd  hh24:mi:ss:ff
日期的运算: 加减(整数天),sysdate-1
如: 计算员工工龄
sysdate-hiredate 天
months_between(sysdate,hiredate) 实际的月
add_months 加月 add_months(sysdate,n) n可正负
last_day(sysdate) 月最后一天
next_day  下一个星期 如: next_day(sysdate,'星期一') 下个星期一的日期
round(number,小数位数正负都行) 四舍五入 针对日期函数
round(to_date ('22-AUG-03'),'YEAR') would return '01-JAN-04'
trunc(number,小数位数) 截断 针对日期函数
trunc(to_date('22-AUG-03'), 'YEAR') would return '01-JAN-03'

4.转换函数
隐式函数:  deptno='10' deptno=10 hiredate='yyyy-mm-dd'
number--> character  to_char(sal,'L9,999.99') 人民币格式字符串
character--->number  to_number('99.99')
date---->character  to_char(sysdate,'yyyy-mm-dd hh24:mi:ss "今天"day')
character-->date        to_date('2016-11-23','yyyy-mm-dd')

5. 聚组函数
avg  求平均值
select avg(sal) from emp; 所有员工平均工资
sum  求和
select sum(sal) from emp; 所有员工工资之和
count 求行数
select count(1) from emp; 所有员工的数量
min  求最小值
select min(sal) from emp; 最少工资多少
max  求最大值
select max(sal) from emp; 最大工资多少

6.其他函数
nvl(e1,e2)
nvl2(e1,e2,e3) e1为null 返回e3 否则返回e2
nullif(a,b) 当a=b的时候 返回null  否则返回a
coalesce(e1,e2,e3,,,) 从左到右 找第一个不为null的值
decode函数
语法:
decode(exp,ser1,res1,ser2,res2,,,,defualt);
案例:
decode(job,'manager',sal+1000,,,,,sal+100);

decode函数的原理是case语句:

语法:
case  exp
when  com_epr then return_exp
when  com_epr then return_exp
when  com_epr then return_exp
else  return_exp
end;
案例:
select  sal 涨前,
case job
when 'manager' then sal + 100
when ....
else sal+300
end  涨后

7.行转列函数
wm_concat函数
如:
select deptno ,wm_concat(ename) names,wm_concat(sal) sals from emp group by deptno;
col sals for a50; 列宽
col names for a50;


分组查询

按列或者函数分组,分组后select后面只能跟分组之后的列,或聚合函数,或子查询

案例1:

统计每年入职的员工人数
select to_char(hiredate,'yyyy') y, count(1) from emp group by to_char(hiredate,'yyyy');

案例2:
每个部门的平均工资
select avg(sal),deptno from emp group by deptno;


多表查询

等值连接
select * from emp,dept where emp.deptno = dept.deptno;
不等值连接
select * from emp,dept where emp.deptno <> dept.deptno;
内连接
select * from emp e inner join dept d on e.deptno = d.deptno; 
外连接
select  * from emp e left join dept d on e.deptno = d.deptno; 左外连接
select  * from emp e ,  dept d where  e.deptno = d.deptno(+); 左外连接
select  * from emp e right join dept d on e.deptno = d.deptno; 右外连接
select  * from emp e ,  dept d where  e.deptno(+) = d.deptno; 右外连接
select  * from emp e full join dept d on e.deptno = d.deptno;  全外连接

自连接
不适合操作大表


子查询

从行列角度子查询主要有三种:

单行子查询
单行子查询常用的操作符号:> < >= <= = <>

查询出高于10部门平均工资的员工信息
select * from emp where sal > (select avg(sal) from emp where deptno=10);

多行子查询
多行子查询常用的操作符号: in   not in  any all exists
注意:子查询中的null  not in(null) 统计不出

查询出比10部门任何员工薪资高的员工信息
select * from emp where sal > any(select sal from emp where deptno = 10);

多列子查询
和10号部门同名同工作的员工信息(实际用法较少):
select * from emp where (ename,job) in (select ename,job from emp where deptno = 10)

从子查询出现位置来分析主要有六种:

1.  select 后面子查询(必须是单行子查询)
获取员工的名字和部门名字

select ename,(select dname from dept where dept.deptno=emp.deptno) dname from emp;

2.  from 后面子查询
查询emp表中经理信息:

select distinct e1.* from emp e1,(select mgr from emp) e2 where e1.empno = e2.mgr;

3.  where 后面子查询
薪资高于10号部门平均工资的所有员工信息:

select * from emp where sal > (select avg(sal) from emp where deptno=10);

4.  having 后面子查询
有哪些部门的平均工资高于30号部门平均工资

select deptno,avg(sal) from emp group by deptno having avg(sal) > (select avg(sal) from emp where deptno=30);

5. 在DDL中使用子查询
create table tname as 子查询
如:
create table ttemp as select * from emp where 1=2;(不要数据)
create table ttemp as select * from emp;(要数据)

6.  insert 后面子查询
参考下面DDL中使用子查询

insert into ttemp select * from emp;

子查询的两个应用案例:
1. 子查询去掉重复行问题rowid

delete from test_data t1 where rowid > (select min(rowid) from test_data t2 where t1.D_NAME = t2.D_NAME and t1.AGE = t2.AGE );

2. 分页问题rownum

select * from (select rownum num,emp.* from emp) where num >=3 and num <=6;


结果排序

order by的特点:

order by 后面 + 列,表达式,别名,序号(列序号从1开始)
如果排序多列,按顺序排(先排第一个列,如果有desc 是针对一个列的,如果每个列都降序,那么每列都加desc)
如果排序的列有多个null值,降序排序的时候,null显示在前面,有数据的按降序显示在null的后面
如果要显示在null的前面,那么需要在原sql语句的后面加 nulls last (原因是null值最大)


集合运算

union  并集:两个集合取并集,自动排序,去掉重复行

select ename,sal,deptno from emp where sal > 1000
union
select ename,sal,deptno from emp where deptno = 30;

union all 并集:两个结合取并集,不排序,不去掉重复行

select ename,sal,deptno from emp where sal > 1000
union all
select ename,sal,deptno from emp where deptno = 30;

intersect 交集:第一个集合减第二个集合

select ename,sal,deptno from emp where sal > 1000
intersect
select ename,sal,deptno from emp where deptno = 30;

minus 差集:第一个集合减第二个集合

select ename,sal,deptno from emp where sal > 1000
minus
select ename,sal,deptno from emp where deptno = 30;

特点: 列的个数要一致
不够的列可以用null来代替


sql查询的综合案例(掌握,强化)

查询出高于本部门平均工资的员工信息

分析:
部门的平均工资
select deptno,avg(sal) from emp group by deptno;
薪水大于平均工资

select * from emp e1
where sal > (select avg(sal) from emp e2 where e2.DEPTNO = e1.DEPTNO group by deptno);

select * from emp e1
where sal > (select avg(sal) from emp e2 group by deptno having  e2.DEPTNO = e1.DEPTNo);


列出 达拉斯加工作的人中, 比纽约平均工资高的人

查询出阿拉斯加工作的人
select * from emp where deptno = (select deptno from dept where loc='DALLAS');
纽约平均工资
select avg(sal) from emp e2 where deptno=(select deptno from dept where loc='NEW YORK') group by deptno
结果:
select * from emp
where
deptno = (select deptno from dept where loc='DALLAS')
and
sal > (select avg(sal) from emp e2 where deptno=(select deptno from dept where loc='NEW YORK') group by deptno);


工作超过5年的员工的名字和部门以及其领导的姓名和部门

分析:
1.  条件
工作超过5年
select * from emp where to_char(sysdate,'yyyy') - to_char(hiredate,'yyyy') > 5;
2.  结果
员工的名字和部门名字以及其领导的姓名和部门

select (select dname from dept d where d.deptno = e.deptno) 部门名字,ename,
(select ename dname from emp e1 where e1.empno = e.mgr) mgrname ,
(select (select dname from dept d where d.deptno = e1.deptno) dname from emp e1 where e1.empno =e.mgr) dname
from emp e
where to_char(sysdate,'yyyy') - to_char(hiredate,'yyyy') > 5;


授权(DCL:Data Control Language)

grant(授权)
revoke(取消授权)

如:grant create synonym to scott; 赋予scott用户有创建同义词的权限


视图(DDL:Data Definition Language)

本质: 对查询语句做了封装,不真实的存放数据,数据还是表中存储。所以通过视图对数据操作,本质还是看表的约束。

grant create view to scott;授予创建视图的权限

创建视图:
create view emp_dept as select ename,
b04d
dname from emp e1,dept d1 where e1.deptno = d1.deptno;


索引(DDL:Data Definition Language)

索引表
B-树 索引(单列)
create  index in_t_name on t1(t);
位图 索引 (多列)
create bitmap index in_t_name on t1(t);
函数索引
create index in_emp_hiredate on emp(to_char(hiredate,'yyyy-mm-dd'));

索引重构alter index 名字  rebuild
alter index in_emp_hiredate rebuild
索引的优点:
提供检索数据的效率
索引的缺点:
反向影响增删改的效率
索引是否创建的分析:
1. 数据量大,经常按某列做查询条件,给该列创建索引
2. 如果经常做增删改操作,不建议创建索引
3. 数据量小(不超过1w条数据),不要建索引
SQL优化:
让索引查询生效
低效率:
select * from emp where hiredate = '1988-10-20';
高效率:
select * from emp where to_char(hiredate,'yyyy-mm-dd') =   '1988-10-20';


序列(DDL:Data Definition Language)

pl/sql工具可视化创建
在内存中,回滚 关机 不连续
REATE SEQUENCE TEST_SEQ INCREMENT BY 1 START WITH 1 MAXVALUE 2000000 MINVALUE 1 CACHE 20;


同义词(DDL:Data Definition Language)

首先要授予创建同义词的权限:
grant create synonym  to scott;
创建同义词(别名)
create synonym hh for emp;
select * from hh;  和 select * from emp;一样


表的高级管理(DDL:Data Definition Language)

表的五大约束:
create table t_student(t_id integer,t_sex char(2),t_age integer);

create table t_teacher(tc_id integer primary key,tc_name varchar2(10));
//给学生表添加外键列
alter table t_student add  tc_id integer;

//1. 主键约束
alter table t_student add constraint pk_t_student_t_id primary key(t_id);
非空 唯一
//2. 唯一性约束
alter table t_student add constraint unique_stu_name unique(t_name);
//3. 非空约束
alter table t_student modify t_name not null;
//4. 外键约束
alter table t_student add constraint fk_stu_tc_id_tea foreign key(tc_id) references t_teacher(tc_id);
//5. 检查约束
alter table t_student add constraint ck_age check(t_age between 1 and 200);
alter table t_student add constraint ck_sex check(t_sex in ('男','女'));

表的三大范式:
1. 所有的列都是不可分割的最小单元
2. 所有的非主键列都完全依赖主键列
3. 非主键列之间不存在传递依赖

数据库设计原则:
1.分析系统中所有的数据(对象,表)
2.确定数据与数据之间的关系(一对一,一对多,多对多)


PowerDesigner的使用

设置生成的sql语句不带引号(Database—>Edit Current DBMS…)



视图工具显示(tools—>Customize Toolbars…)



数据库链路(权限)

1. 设置权限
grant create database  link to scott;

2. 创建链路
create database  link linkhm2 connect to scott identified by tiger using '192.168.34.188/orcl';

3. 使用
select * from emp@linkhm2;

4. 创建别名
grant create synonym to scott;
create synonym emp1 for emp@linkhm2;(同义词)
select * from emp1;


删除闪回

create table tt(id int);

insert into tt values(1);
insert into tt values(2);
insert into tt values(3);
commit;

select timestamp_to_scn(sysdate) from dual;

TIMESTAMP_TO_SCN(SYSDATE)
-------------------------
742273

闪回前必须启动行移动功能
alter table tt enable row movement;

delete from tt where id = 2;
commit;

flashback table tt to SCN 742273;//回滚
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: