oracle基础
关系图
sql包含四种程序设计语言类别的语句:
-
数据定义语言(DDL)
-
数据操作语言(DML)
-
数据查询语句(DQL)
-
数据控制语言(DCL)
-
事务控制语言(TCL)
- SAVEPOINT - 设置保存点
- ROLLBACK - 回滚
- COMMIT - 提交
基础知识
数据类型
-
字符型
-
char
-
定长,最大2000字符
- char(10) 小韩”前四个字符放“小韩”后添6个空格补全
-
-
varchar2(20)
-
变长,最大4000字符
- varchar2(10) 小寒oracle分配四个字符这样可以节省空间
-
-
clob(character large object)
- 字符型大对象,最大4G
-
-
数字型
-
日期
-
-
blob
-
二进制数据 可以存放图片、声音
- 4G
-
-
运算符
-
关系运算符 > < >= <= = !=(或<>)
- 如果是null,则使用is null或is not null.
-
逻辑运算符 or and not
- select * from emp where empno=7788 or empno=7369
- select * from emp where deptno=20 and job ='CLERK' ;
- select * from emp where not ( empno=7788 or empno=7369 )
-
算数运算
-
四则运算
-
null参与运算时,结果永远为null-->解决nvl/nvl2
- nvl(a,b):如果a为null,则值为b -->if
- nvl2(a,b,c):如果a是null,则值为c,否则为b; --if..else..
-
-
连接符 concat、||
- select concat('hello','123') from dual ;
- select 'hello'||'123' from dual ;
函数
-
单行函数:
-
① 字符函数
-
a.lower /upper/initcap
- select 'Hello World' 原始, lower('Hello World') 小写,upper('Hello World') 大写, initcap('hello world') 首字母大写 from dual ;
-
b.substr(str,begin):将str从begin开始截取
-
select substr('Hello world',3) from dual ;
- --Oracle从1开始数
-
-
c.substr(str,begin,len) :将str从begin开始截取,截取的长度是len
- select substr('Hello world',3,3) from dual ;
-
d.length/lengthb
-
e.instr(a,b) :在a中,查找b的位置(从1开始数)。如果不存在,返回0 ;
- select instr('hello world','ll') from dual ;--3
- select instr('hello world','llw') from dual ;--0
-
f.lpad左填充、rpad右填充
- select lpad('hello',10,'') 左填充, rpad('hello',10,'') from dual ;
-
g.trim()
- trim():去掉左右两端空格
- trim('X' from str)去掉str左右两段的X
- select trim('X' from 'XXhello worldXXX') from dual ;
-
h.replace()
-
select replace('Hello world','l','*') from dual ;
- 将l变成*
-
-
-
②数值函数
-
③ 日期函数
-
a.关键字sysdate:获取当前时间
- select sysdate from dual ;
-
b.格式化时间 to_char(时间,格式)
- select to_date('2005-01-01 13:14:20','yyyy-MM-dd HH24:mi:ss') from dual;
-
c.日期 可以+/-数字
- select (sysdate-1) 昨天,sysdate 今天,sysdate+1 明天 from dual ;
-
d.日期只能-日期,不能+日期
- select sysdate-hiredate 工作天数 from emp ;
-
e. months_between(日期1,日期2) :相差的月数。日期1- 日期2
- select months_between(sysdate,hiredate) 工作月数 from emp ;
-
f: add_months(时间,月数):增加月份
- select add_months(sysdate,3) from dual ;
-
g. last_day(时间) :当月的最后一天
- select last_day(sysdate) from dual ;
-
i. next_day(时间,'星期N'):下一个星期N是哪一天
- select next_day(sysdate,'星期五') from dual ;
-
j. 四舍五入
- select round(sysdate,'month') 月,round(sysdate,'year') from dual ;
-
h.截取(舍尾)
-
日期格式
-
-
④通用函数
-
a.nvl/nvl2
-
b.nullif(a,b) :如果a=b,则返回null;否则返回a
- select nullif('hello','hello') from dual ;--null
- select nullif('hello','world') from dual ;--hello
-
c. coalesce :从左往右,寻找第一个不为null的值
- select coalesce(null,null,'c') from dual ;
-
-
1)decode(字段,条件1,表达式1,条件2,表达式2,...,条件n,表达式n,其他)
- select ename, sal 涨前,job,decode(job,'PRESIDENT',sal+1000,'MANAGER',sal+800,sal+400) 涨后 from emp ;
-
- case表达式(case...end)
- select ename, sal 涨前,job, case job
when 'PRESIDENT' then sal+1000
when 'MANAGER' then sal+800
else sal+400
end 涨后
from emp ;
-
-
-
⑤转换函数
- 数字/日期<-->字符串
-
-
多行函数
-
count(*) :求总数量
-
sum 求和
-
avg 求平均值
-
max最大值
-
min最小值
-
select sum(sal) 总工资,avg(sal) 平均工资, max(sal) 最高工资,min(sal) 最低工资 from emp ;
-
基本设置
在Oracle中调用dos命令: host dos命令;
- 清屏 host cls
连接命令
文件操作命令
-
start和@
-
edit
-
spool
显示和设置环境变量
-
可以用来控制输出的各种格式,set show
-
linesize
-
pagesize
-
设置列宽
-
设置类型为字符串的列:
- col 列名 for a长度 ;
- col ename for a10 ;
-
设置类型为数字的列:
- col 列名 for a9个数; (实际长度为9的个数+1)
-
-
显示运行时间
- set timing on;
修改写错的sql
追加命令 a命令(append):在上一次的sql后追加语句,追加完毕回车 /
-
select * from emp;
-
a order by sal ;
-
过程:
- select * from emp order by sal;
-
-注意:a后面有2个空格。
基本设定
伪表
- dual 存储单行单列,用于学习、测试使用
- select 'hello'||'world' from emp;
- select 'hello'||'world' from dual;
DDL
操作数据库
操作表
-
C
-
建表
- create table student
(sno number(3),
sname varchar2(20))
- create table student
-
-
R
-
查看当前用户所有
- select * form tab;
-
查看表的结构
- desc 表名
-
-
U
-
D
- 删除表:drop table 表名;
- 清空回收站purge recyclebin;
约束6个
-
6个约束
-
主键和唯一键的区别:
- a.主键不能为null,唯一键可以为null
- b.一张表只能设置一次主键(主键可以是一个,也可以是复合主键),但可以设置多次唯一键
-
作为范围可以分为两大类
-
二者的区别:
-
列级约束
-
create table student
(
stuNo number(3) primary key, --主键约束
stuName varchar(20) unique ,--非空约束not null、唯一约束
stuAddress varchar(50) default '陕西西安' check( length(stuAddress)>2 and length(stuAddress)<20 ),--默认约束、check约束
subId number(3)
) -
注意事项
-
约束命名
-
constraint 约束类型_约束列
-
命名规则
- 给主键约束命名:constraint PK_stuno
- 给检查约束命名:constraint CK_stuaddress
- 唯一约束... : constraint UQ_stuName
- 非空..: constraint NN_stuName
- 外键... : constraint FK_子表的名字_父表的名字
- 默认约束..: 一般不需要命名
-
注意事项: 约束名 在当前用户下的所有表之间 共用。
-
创建带约束的表
- create table student1
(
stuNo number(3) constraint PK_stuno primary key, --主键约束
stuName varchar(20) constraint NN_stuName not null constraint UQ_stuName unique ,--非空约束、唯一约束
stuAddress varchar(50) default '陕西西安' constraint CK_stuAddress check( length(stuAddress)>2 and length(stuAddress)<20 ),--默认约束、check约束
subId number(3)
)
- create table student1
-
-
-
表级约束
- create table student2
(
stuNo number(3),
stuName varchar2(20),
stuAddress varchar2(50),
subId number(3),
constraint PK_stuNo1 primary key(stuNo) ,--表级约束
constraint UQ_stuName_subId unique(stuName,subId) ,//唯一约束作用于两列
constraint CK_stuAddress1 check(length(stuAddress)>2)
);
- create table student2
-
-
外键(完整约束条件)
-
创建外键
- create table sub
(
sId number(3) primary key, --外键所指向的列 必须是主键或唯一键
sname varchar(20)
); - create table student3
(
stuNo number(3),
stuName varchar2(20),
subId number(3),
constraint FK_student3_sub foreign key(subId) references sub(sId) –表级外键约束
);
- create table sub
-
要求外键列数据必须在主表的主键列存在或是为NULL。
-
表级约束
- CREATE TABLE table_name
(column_1 datatype ,
column_2 datatype ,
...
CONSTRAINT fk_column FOREIGN KEY (column_1, column_i, ... column_n) REFERENCES parent_table (column_1, column_i, ... column_n)
);
- CREATE TABLE table_name
-
列级约束
- CREATE TABLE table_name
(column_1 datatype ,
column_2 datatype CONSTRAINT fk_column REFERENCES parent_table (column_name),
...
);
- CREATE TABLE table_name
-
级联置空、级联删除
-
使用外键的一些设置
-
-
追加约束
-
① alter table 表名 add constraint 约束名 具体的约束
-
追加唯一约束:
- alter table student5 add constraint UQ_stuname5 unique(stuName);
-
追加主键约束:
- alter table student5 add constraint PK_stuno5 primary key(stuno);
-
追加检查约束:
- alter table student5 add constraint CK_stuname5 check( length(stuname)>2 and length(stuname)<20 );
-
追加外键约束:
- alter table student5 add constraint FK_student5_sub foreign key(subid) references sub(sid) ;
-
-
② alter table 表名 modify 约束名 具体的约束
-
-
删除约束
-
完整性约束
- 域完整性:对“列”的数据进行限制
- 实体完整性:对“行”的数据进行限制
- 引用完整性:多张表的数据 进行限制(外键)
- 自定义完整性:开发者自己定义的 约束条件 (通过触发器实现)
DML
添加数据
- insert into student(sno,sname) values(1,'zs') ;
- insert into student values(2,'ls') ;
删除数据(不是删除表)
-
delete from student where sno=1;
- 删除一条数据
-
delete from 表名;
- 删除所有记录,表结构还在,写日志,可以恢复的,速度慢
-
drop table student;
- 删除表结构和数据
-
truncate table student;
修改数据
- update student set sname='lisi',sno=20 where sno =2;
DQL
基本select查询
-
select * from 表名;
- select * from emp;
-
基础查询
-
多字段查询
-
select hiredate from emp;
-
查询全部列
- select * from emp;
- select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp ;
- 推荐使用第二种。
-
-
别名
-
select ename as "姓名",job as "工作" from emp;
-
select ename "姓名",job "工作" from emp;
-
select ename 姓名 ,job 工作 from emp; --不推荐,如下是错的:
- select ename "from" ,job 工作 from emp;
-
-
distinct去重
- select distinct job,deptno from emp ;
-
列的计算
- select ename,sal*12 from emp;
-
-
条件查询where
-
排序查询
-
select * from .... where... order by 字段名|别名|表达式|数字 asc(默认)|desc ;
-
多个字段进行排序
- ..order by 字段名1,字段名2,....,字段N ;
-
如果排序存在null:在Oracle中Null最大。如果需要null排在最后,使用nulls last ;
-
-
分组
多表查询
-
连接查询
-
内连接
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e,dept d
where e.deptno = d.deptno - select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e
inner join dept d
on e.deptno = d.deptno;
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
-
外连接
-
左外
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e,dept d
where e.deptno = d.deptno(+) ; - select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e
left outer join dept d
on e.deptno = d.deptno;
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
-
右外
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e,dept d
where e.deptno(+) = d.deptno - select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e
right outer join dept d
on e.deptno = d.deptno;
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
-
完全
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e
full outer join dept d
on e.deptno = d.deptno;
- select e.empno,e.ename,e.deptno,d.deptno,d.dname
-
-
自连接
-
将一张表,通过别名“视为”不同的表
- select e.ename 员工, b.ename 领导 from emp e,emp b where e.mgr = b.empno ;
-
-
-
集合运算
分页sql
TCL事务
事务流程
-
创建保存点
- savepoint aa;
-
回滚至保存点
- rollback to aa;
-
提交
- commit
DCL
用户管理
-
创建用户
权限管理
- 权限
- 系统权限
- 用户对数据库的相关权限
- 140多个系统权限
- 对象权限
- 用户对其他用户的数据对象操作的权限
- Oracle拥有25个对象权限
- 角色(一组权限)
- 预定义角色
- 自定义角色
-
角色
- 从系统权限中挑出来的权限
- Connect角色:一些基本权限
- Dba角色
- Resource角色:让用户在任何表空间建表
-
授予权限
- grant select on emp to xiaoming
-
- select * from scott.emp;
-
收回权限
-
权限维护
口令管理
数据库设计
三大范式
-
1NF
- 确保每列原子性(不可分),可以避免数据冗余(重复)
-
2NF
- 宏观:确保每张表 只描述一件事情
- 微观:除了主键以外的其他列,都必须依赖于主键
-
3NF
- 除了主键意外的其他列,都必须 不传递依赖于主键
-
注意
如果查询的数据包含null,使用范围查询in和Not in时需要注意:
in
-
等价于1
- select ...from emp where comm in (a,b) ;
- select ...from emp where comm=a or comm=b ;
-
等价于2
- select * from emp where comm in (300,null) ;
- select * from emp where comm =300 or comm = null ;
on
-
等价于
- select * from emp where comm not in (300,null) ;
- select * from emp where comm != 300 and comm !=null ;
(判断是否是Null: is null , is not null)
- null!=null -->false
- null=null -->false
复制表:批量增加 -->创建表myemp, 批量增加数据
create table myemp as select empno,ename,job from emp;
如何增加海量数据:
a. sql Loader工具 b.数据泵 c.外部表
序列
可以实现自动增长
序列的两个属性:
语法
- create sequence 序列名
increment by 步长
start with 初始值
maxvalue|nomaxvalue
minvalue|nominvalue
cycle|nocycle
cache 3|no cache
示例:
- create sequence myseq ; -- [1] 2 3 4 5 6
裂缝
- 使用序列,有可能产生裂缝:
- 系统异常、回滚、多表使用同一个序列
修改序列
- 【alter】 sequence 序列名
increment by 步长2
start with 初始值
maxvalue|nomaxvalue
minvalue|nominvalue
cycle|nocycle
cache 3|no cache - 注意:修改序列 只会影响修改以后的值。
- insert into student values(myseq.nextval ,....) ;
删除序列
- drop sequence 序列名;
- drop sequence myseq;
删除重复数据
准备重复数据
- create table mystudent
(
stuno number ,
stuname varchar2(20),
stuage number
);
insert into mystudent values(1,'zs',23);
insert into mystudent values(1,'zs',23);
insert into mystudent values(2,'ls',24);
insert into mystudent values(2,'ls',24);
insert into mystudent values(3,'ww',55);
尝试1:distinct
- delete from mystudent where stuno in (
select distinct stuno from mystudent );
尝试2:伪列(rownum,rowid)
-
删除全部数据
- delete from 表名;
- truncate table 表名; --效率高
-
分析
- select rowid, s.* from mystudent s;发现数据插入的越晚,rowid越大;数据插入越早,rowid越小。
rowid的组成AAAST+ AAE AAAAJV AAA:
数据对象号(6位):AAAST+
相关数据文件号(3位):AAE
数据块号(6位):AAAAJV
数据块中行号(3位):AAA
- select rowid, s.* from mystudent s;发现数据插入的越晚,rowid越大;数据插入越早,rowid越小。
-
删除重复的行:
-
将重复数据分为一组:
- select min(rowid) from mystudent
group by stuno,stuname,stuage ;
- select min(rowid) from mystudent
-
数据插入越早,rowid越小。
- 1组
insert into mystudent values(1,'zs',23); --rowid:AAAST+AAEAAAAJVAAA --第一条
insert into mystudent values(1,'zs',23); --rowid:AAAST+AAEAAAAJVAAB --x
2组
insert into mystudent values(2,'ls',24); --rowid:AAAST+AAEAAAAJVAAC --第二条
insert into mystudent values(2,'ls',24);--rowid:AAAST+AAEAAAAJVAAD --y
3组
insert into mystudent values(3,'ww',55);--rowid:AAAST+AAEAAAAJVAAE --第三条
- 1组
-
最终sql:
- delete from mystudent where rowid
not in(
select min(rowid) from mystudent
group by stuno,stuname,stuage) ;
- delete from mystudent where rowid
-
思路
- 将相同数据分为一组-->在每组中 找到最小的rowid,即min(rowid) -->删除不是最小的rowid,即delete from ...not in (...)
-
尝试:
-
查询每种工作的最低工资,以及领取该工资的员工姓名。
select min(sal),job from emp
group by job ;select e.ename ,t.job, t.minsal from emp e , (select min(sal) minsal ,job from emp
group by job) t
where e.empno = t.empno ;
--where t. minsal = e.sal and t.job = e.job ;t
minsal, job
a b
c d
e f
查询出工资不超过2500的人数最多的部门名称。
分析:
select d.deptno,d.dname from dept d ,emp e
where d.deptno = e.deptno and e.sal<=2500
group by d.deptno,d.dname
having count() = ( select max(count()) from emp
where sal<=2500
group by deptno
);
查询出管理 员工人数最多的人的名字 和 他管理的人的名字。
先查出管理最多的员工数 (最多管理几个人)
select max(cn) from
(select count(mgr) cn, mgr from emp
group by mgr) t ;
再查出与最多员工 相对应的MRG
select mgr from emp
group by mgr
having count(mgr) = (select max(cn) from
(select count(mgr) cn, mgr from emp
group by mgr) t );
最终:
select e.ename 员工 , b.ename 领导 from emp e ,emp b
where e.mgr = b.empno
and e.mgr = (select mgr from emp
group by mgr
having count(mgr) = (select max(cn) from
(select count(mgr) cn,mgr from emp
group by mgr) t ));
-
-
视图
从表中抽取出的逻辑上相关的数据集合(字段、列)
员工编号、年薪、部门名称
select empno,sal*12,dname from emp e,dept d where e.deptno = d.deptno ;
select * from emp ;
创建视图
- create view 视图名
as
查询语句 ;
create view myempview
as
select empno 编号,sal*12 年薪,dname 部门名称 from emp e,dept d
where e.deptno = d.deptno ;
小结:
对视图的增删改
create view baseview
as
select empno,ename,job from emp
with read only;//设置只读
- with check option
- 确保对视图的操作,必须满足where子句
create view empdeptno20
as
select * from emp where deptno=20
with check option;
视图分类
视图不建议用于DML。但如果非要用DML,则必须满意以下条件:
-
①当出现以下之一时,不能Insert/update
-
②当出现以下之一时,不能delete
-
create view testview
as
select avg(sal) 平均工资,sum(sal) 总工资,job from emp group by job ;
--没有出现在组函数中的列,必须出现在group by后。
DQL:查询语句
DML:增删改语句
DDL:数据库定义语言,create table/view/sequence
索引(index)
并不是所有情况都适合建立索引:
-
不合适:
- 数据集中的列,不经常在where中使用的列,数据量小,经常更新
Oracle中的索引类型: B树索引(默认)、位图索引(矩阵索引)
创建索引
- create index myindex on emp(deptno);
如果要观察是否使用了索引:查看sql执行计划
删除索引 drop index myindex;
同义词
在scott用户中查询hr用户中的 employees表:
- select * from hr.employees; --需要先授权 :sys账户中 grant select on hr.employees to scott;
私有同义词:谁创建谁使用。
- create puyblic synonym hremp for hr.employees;
公有同义词:无论谁创建,任何人都可以使用。
- 需要先授权 :sys账户中 grant create public synonym to scott;
- 创建公有同义词:
- 给hr.employees起别名:
create synonym hremp for hr.employees;
--需要先授权:sys账户中grant create synonym to scott;
删除同义词 drop synonym hremp ;
撤销权限:
存储过程
语法
- create procedure 名字(参数列表 ) as PLsql语句 ;--没有declare
create procedure myPro
as
pnum number:=10;
begin
dbms_output.put_line('hello');
dbms_output.put_line('world'||pnum);
end;
调用:
有参:存储过程中,参数 in/out
存储函数
最大区别:
语法
- create function 名字(参数列表 )
return 类型
as
PLsql语句 ;--没有declare
return 值; - 虽然return和out可以混用,但一般建议:如果返回值 有1个,则用retrun;否则(多个 或0个)用out.
小节
查询某个部门的 所有员工信息。
输入参数:deptno
输出参数:所有员工信息 -- List
存储过程 /存储函数 不能直接返回光标。 -- package
小结:要返回光标,必须先建包package。
包:包头+包体
其中 包头,相当于 接口; 包体,相当于实现类。
创建包头:右键程序包-->新建
创建包体:右键包头-->创建主体
可以在包中 建立存储过程。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。