Oracle基本用法(一)
一、简介
数据库:Oracle数据库的概念和其他数据库不一样,这里的数据库是一个操作系统只有一个库,可以看做Oracle就是一个大的数据库。
实例:一个Oracle实例有一系列的后台进程和内存结构组成,一个数据库可以有n个实例。
用户:用户是在实例下面创建的。不同的实例可以创建相同名字的用户。
表空间:表空间是Oracle对物理数据库上相关数据文件的逻辑映射。一个数据库在逻辑上被划分成一到若干个表空间,每个表空间包含了在逻辑上相关联的一组结构。每个数据库至少有一个表空间(称之为system表空间)。每个表空间由同一磁盘上的一个或多个文件组成,这些文件叫做数据文件。一个数据文件只能属于一个表空间。
数据文件:数据文件是数据库的物理存储单位。数据库的数据是存储在表空间中的,真正是在某一个或者多个数据文件中。而一个表空间可以由一个或者多个数据文件组成,一个数据文件只能属于一个表空间,一旦数据文件被加入到某个表空间之后,就不能删除这个数据文件,如果要删除某个数据文件,只能删除其所属表空间才行。
由于Oracle的数据库不是普通的概念,Oracle是由用户和表空间对数据进行管理和存放的。但是表不是由表空间去操作的,而是由用户去查询的。因为不同用户可以在同一个表空间建立同一个名字的表!这里区分就是用户了。
二、demo
数据库表结构
create table emp(
empno number(4),
ename varchar2(10),
job varchar2(9),
mgr number(4),
hiredate date,
sal number(7,2),
comm number(7,2),
deptno number(2)
);
select * from emp;
create sequence s_emp;
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (s_emp.nextval,'莫逸风','开发',0,sysdate,3000,300,1);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (s_emp.nextval,'莫逸风2','开发1',0,sysdate,1000,300,2);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (s_emp.nextval,'莫逸风3','开发',0,sysdate,2000,300,1);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (s_emp.nextval,'莫逸风4','开发1',0,sysdate,3000,300,2);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (s_emp.nextval,'莫逸风5','开发',0,sysdate,4000,300,1);
create table dept(
deptno number(2),
dname varchar2(14),
loc varchar2(13)
);
select * from dept;
insert into dept (deptno,dname,loc) values (1,'开发','开发A区');
insert into dept (deptno,dname,loc) values (2,'开发1','开发B区');
create table salgrade(
grade number,
losal number,
hisal number
);
select * from salgrade;
create table bonus(
ename varchar2(10),
job varchar2(9),
sal number,
comm number
);
select * from bonus;
insert into bonus (ename,job,sal,comm) values ('莫逸风','开发',3000,300);
insert into bonus (ename,job,sal,comm) values ('莫逸风2','开发1',1000,300);
insert into bonus (ename,job,sal,comm) values ('莫逸风3','开发',2000,300);
Demo
--创建表空间moyifeng指定文件存储位置‘D:...’指定文件大小100m,指定文件自增10m
create tablespace moyifeng
datafile 'D:\Project\OracleData\moyifeng.dbf'
size 100m
autoextend on
next 10m;
--删除表空间,drop后需要找到文件然后删除
drop tablespace moyifeng;
--创建用户,指定密码,指定表空间
create user moyifeng
identified by root
default tablespace moyifeng;
--给用户授权
--Oracle数据库中常用角色
connect--链接角色,基本角色
resource--开发者角色
dba--超级管理员角色
--给moyifeng授予dba角色
grant dba to moyifeng;
--切换到moyifeng用户下Session log off log in
--Oracle数据类型
Varchar,varchar2--表示一个字符串,常用的是varchar2,可变字符自动缩减内存空间,不会增加
NUMBER--NUMBER(n)表示一个整数,长度是n
--NUMBER(m,n):表示一个小数,总长度是m,小数是n,整数是m-n
DATA--表示日期类型,相当于mysql中的datatime
CLOB--大对象,表示大文本数据类型,可存4G(应用场景文字)
BLOB--大对象,表示二进制数据,可存4G(应用场景视频)
--创建一个person表
create table person(
pid number(20),
pname varchar2(10)
);
select * from person;
--添加一条记录(增删改都需要提交)
insert into person (pid, pname) values (1,'小明');
commit;
--修改一条记录
update person set pname='小马' where pid = 1;
commit;
--删除一条数据
delete person where pid = 1;
commit;
--删除表中全部记录
delete from person;
--删除表结构
drop table person;
--先删除表,再创建表。效果等同于删除表中全部数据
--再数据量大的情况下,尤其在表中带有索引的情况下,该操作效率高。
--索引可以提高查询效率,但是会影响增删改效率
truncate table person;
--序列:不属于任何一张表,但可以逻辑和表做绑定。
--序列:默认从1开始,依次递增,主要用来给主键赋值使用。
--dual:虚标,只是为了补全语法,没有任何意义(Oracle中查询必须有from)
create sequence s_person;
select s_person.nextval from dual;--下一个
select s_person.currval from dual;--自己
insert into person (pid, pname) values (s_person.nextval,'小明');
commit;
select * from person;
--单行函数:作用于一行,返回一个值
--字符函数
select upper('yes') from dual;
select lower('YES') from dual;
--数值函数
select round(26.18) from dual;--四舍五入 26
select round(26.18,1) from dual;--四舍五入 26.1
select round(26.18,-1) from dual;--四舍五入 30
select trunc(26.18) from dual;--直接截取
select trunc(26.18,1) from dual;--直接截取
select trunc(26.18,-1) from dual;--直接截取
select mod(10,3) from dual;--求余
--日期函数
--查出emp表中所有员工入职时间距离现在几天
select sysdate-e.hiredate from emp e;
--算出明天此刻时间
select sysdate+1 from dual;
--查出emp表中所有员工入职时间距离现在几月
select months_between(sysdate,e.hiredate) from emp e;
--查出emp表中所有员工入职时间距离现在几年
select months_between(sysdate,e.hiredate)/12 from equip e;
--查出emp表中所有员工入职时间距离现在几周
select (sysdate-e.hiredate)/7 from emp e;
--转换函数
--日期转字符串
select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;
select to_char(sysdate,'fm yyyy-mm-dd hh:mi:ss') from dual;--去掉7月前面的0
select to_char(sysdate,'fm yyyy-mm-dd hh24:mi:ss') from dual;--24小时计数法
--字符串转日期
select to_date('2020-7-9 23:9:52','fm yyyy-mm-dd hh24:mi:ss') from dual;--24小时计数法
--通用函数
--算出emp表中所有员工的年薪
--奖金里面有null值,如果null值和任意数字做算术运算,结果都是null
select e.sal*12+nvl(e.comm, 0) from emp e;--nvl如果e.comm是null则使用0做计算如果不是null则使用原值
--条件表达式(通用写法,mysql与Oracle通用)
--给emp表中员工起中文表
select e.ename,
case e.ename
when 'a' then '莫'
when 'b' then '逸'
when 'c' then '风'
else '哈哈'
end
from emp e;
--判断emp表中员工工资,如果高于3000显示高收入,如果高于1500低于3000显示中等收入,如果低于1500显示低收入
select e.sal,
case
when e.sal>3000 then '高收入'
when e.sal>1500 then '中等收入'
else '低收入'
end
from emp e;
--Oracle中除了起别名,都用单引号。
--Oracle专用表达式
select e.ename,
decode(e.name,
'a','莫',
'b','逸',
'c','风',
'无名')
from emp e;
--多行函数【聚合函数】:作用于多行,返回一个值
select count(1) from emp;--查询总数量
select sum(sal) from emp;--工资总和
select max(sal) from emp;--最大工资
select min(sal) from emp;--最小工资
select avg(sal) from emp;--平均工资
--分组查询
--查询出每个部门的平均工资
--分组查询中,出现在group by后面的原始列,才能出现在select后面
--没有出现在group by后面的列,想在select后面出现,必须接上聚合函数。
--聚合函数有一个特性,可以吧多行记录变成一个值。
select e.depyno,avg(e.sal)
from emp e
group by e.depyno
--查询平均工资高于2000的部门信息
select e.deptno,avg(e.sal) asal
from emp e
group by e.deptno
having avg(e,sal)>2000
--所有条件都不能使用别名来判断。
--比如下面的条件语句也不能使用别名当条件。因为where的执行顺序优于查询
select ename,sal s from emp where sal>1500;
--查询出每个部门工资高于800的员工的平均工资
select e.deptno
from emp e
where e.sal>800
group by e.deptno;
--where是过滤分组前的数据,having是过滤分组后的数据。
--表现形式:where必须在group by之前,having是在group by之后。
--查询出每个部门工资高于800的员工的平均工资
--然后查询出平均工资高于2000的部门信息
select e.deptno,avg(e.sal)
from emp e
where e.sal>800
group by e.deptno
having avg(e.sal)>2000
--多表查询中的一些概念
--笛卡尔积
select *
from emp e,dept d;--e中8条数据,d中5条数据查询结构40条数据
--等值连接
select *
from emp e,dept d
where e.deptno=d.deptno;
--内连接
select *
from emp e inner join dept d
on e.deptno=d.deptno;
--查询出所有部门以及该部门下的员工信息【外连接】
--右外连接会将右侧所有信息展示出来
select *
from emp e right join dept d
on e.deptno=d.deptno
--查询所有员工信息,以及员工所属部门
select *
from emp e left join dept d
where e.deptno=d.deptno;
--oracle专用外连接
select *
from emp e,dept d
where e.deptno(+)=d.deptno;--等同右外连接
select *
from emp e,dept d
where e.deptno=d.deptno(+);--等同左外连接
--查询比4018号雇员工资高的雇员信息
select *
from emp e
where e.sal > (select sal from emp where emp.deptno=4108)
--查询比4018号雇员工资高同事和4018号雇员工作一样的员工
select * from emp e1
where e1.sal > (select e2.sal from emp e2 where e2.deptno=4108)
and e1.job = (select e3.job from emp e3 where e3.deptno=4108)
--查询每个部门的最低工资和最低工资的雇员和部门名称
select d.dname,a.minsal,e.ename
from dept d,
(select deptno,min(sal) minsal from emp group by deptno) a,
emp e
where d.deptno=a.deptno
and e.sal = a.minsal
--Oracle中的分页
--rownum行号:当我们做select操作的时候,
--每查询出一行,就会在该行上加上一个行号,
--行号从1开始,依次递增,不能跳着走。
--排序操作会影响rownum的顺序
select rownum,e.* from emp e order by e.sal desc
--如果涉及到排序,但是还要使用rownum的话,我们可以嵌套查询
select rownum,t.* from (
select e.* from emp e order by e.sal desc
) t;
--emp表工资倒序排列后每页2条记录查询第二页
select tt.* from
(select rownum a,t.* from (
select e.* from emp e order by e.sal desc
) t where rownum<5
) tt
where a>2;
--查询服务器字符集
select userenv('language') from dual;