1.创建表空间
表空间? ORACLE数据库的逻辑单元。 实例---表空间 一个表空间可以与多个数据文件(物理结构)关联
一个实例下可以建立多个表空间,一个表空间可以建立多个用户、一个用户下可以建立多个表。
create tablespace fan datafile 'D:oracle ablespacefan.dbf' size 100m autoextend on next 10m
fan 为表空间名称
datafile 指定表空间对应的数据文件,名称可以不为fan
size 定义的是表空间的初始大小
autoextend on 自动增长 ,当表空间存储都占满时,自动增长
next 后指定的是一次自动增长的大小。
-- 删除表空间 drop tablespace fan;
2.用户
创建用户:
-- 创建用户 create user zhangsan identified by aaa default tablespace fan
identified by 后边是用户的密码
default tablespace 后边是表空间名称
oracle 数据库与其它数据库产品的区别在于,表和其它的数据库对象都是存储在用户下的。
用户赋权限:
新创建的用户没有任何权限,登陆后会提示
Oracle 中已存在三个重要的角色:connect 角色,resource角色,dba角色。
CONNECT 角色: --连接角色,是授予最终用户的典型权利,最基本的
ALTER SESSION --修改会话
CREATE CLUSTER --建立聚簇
CREATE DATABASE LINK --建立数据库链接
CREATE SEQUENCE --建立序列
CREATE SESSION --建立会话
CREATE SYNONYM --建立同义词
CREATE VIEW --建立视图
RESOURCE 角色: --是授予开发人员的
CREATE CLUSTER --建立聚簇
CREATE PROCEDURE --建立过程
CREATE SEQUENCE --建立序列
CREATE TABLE --建表
CREATE TRIGGER --建立触发器
CREATE TYPE --建立类型
DBA角色:拥有全部特权,是系统最高权限,只有 DBA 才可以创建数据库结构,并且系统权限也需要DBA授出,
且 DBA 用户可以操作全体用户的任意基表,包括删除
grant dba to zhangsan;
进入 system 用户下给用户 zhangsan 赋予 dba 权限,否则无法正常登陆
3.oracle 数据类型
字符型
(1)CHAR : 固定长度的字符类型,最多存储 2000 个字节
(2)VARCHAR2 :可变长度的字符类型,最多存储 4000 个字节 别名varchar,可以兼容其他数据库
(3)LONG : 大文本类型。最大可以存储 2 个 G
数值型
NUMBER : 数值类型
例如:NUMBER(5) 最大可以存的数为 99999
NUMBER(5,2) 最大可以存的数为 999.99
日期型
(1)DATE:日期时间型,精确到秒
(2)TIMESTAMP:精确到秒的小数点后 9 位
二进制型(大数据类型)
(1)CLOB : 存储字符,最大可以存 4 个 G
(2)BLOB:存储图像、声音、视频等二进制数据,最多可以存 4 个 G
4.表的管理
建表:
语法:
Create table 表名(
字段 1 数据类型 [default 默认值],
字段 2 数据类型 [default 默认值],
...
字段 n 数据类型 [default 默认值]
);
范例:创建 person表
create table person( pid number(15), name varchar2(10), gender number(1) default 1, birthday date );
表删除:
语法:DROP TABLE 表名
表的修改:
在 sql 中使用 alter 可以修改表
添加语法:ALTER TABLE 表名称 ADD(列名 1 类型 [DEFAULT 默认值],列名 2 类型 [DEFAULT 默认值]...)
alter table person add (age number(3) default 18, card varchar(18));
修改语法:ALTER TABLE 表名称 MODIFY(列名 1 类型 [DEFAULT 默认值],列名 2 类型 [DEFAULT 默认值]...)
alter table person modify age number(4);
修改列名: ALTER TABLE 表名称 RENAME COLUMN 列名 1 TO 列名 2
alter table person rename column gender to sex;
删除一列:alter table person drop column card;
数据库表数据的更新:
1. INSERT
标准写法:
INSERT INTO 表名[(列名 1,列名 2,...)] VALUES(值 1,值 2,...)
简单写法(不建议):
INSERT INTO 表名 VALUES(值 1,值 2,...)
注意:使用简单的写法必须按照表中的字段的顺序来插入值,而且如果有为空的字段使用 null
insert into person(pid, name, gender, birthday) values(1, '张三', null, to_date('1998-8-16', 'yyyy-MM-dd')); commit;
2. UPDATE
全部修改:UPDATE 表名 SET 列名 1=值 1,列名 2=值 2,....
局部修改:UPDATE 表名 SET 列名 1=值 1,列名 2=值 2,....WHERE 修改条件;
update person set age = 20 where pid = 1; commit;
3. DELETE
语法 : DELETE FROM 表名 WHERE 删除条件;
在删除语句中如果不指定删除条件的话就会删除所有的数据
delete from person where pid = 1; commit;
删除表中全部记录:delete from person;
删除表结构:drop table person; -- 删除表
先删除表,再次创建表,等同于删除表中全部记录,会重建索引:truncate table person;
在数据量大的情况下,尤其在表中带有索引的情况下,该操作效率高(先删除索引,再删表)
索引可以提高查询效率,但是会影响增删改效率
因为 oracle 的事务对数据库的变更的处理,我们必须做提交事务才能让数据真正的插入到数据库中,
在同样在执行完数据库变更的操作后还可以把事务进行回滚,这样就不会插入到数据库。
如果事务提交后则不可以再回滚。
提交:commit;
回滚:rollback;
序列:默认从1开始,依次递增
在很多数据库中都存在一个自动增长的列,如果现在要想在 oracle 中完成自动增长的功能,
则只能依靠序列完成,所有的自动增长操作,需要用户手工完成处理。
语法:
CREATE SEQUENCE 序列名
[INCREMENT BY n] -- 每次增加 n
[START WITH n] -- 默认从 n 开始
[{MAXVALUE/ MINVALUE n|NOMAXVALUE}] -- 最大值,最小值
[{CYCLE|NOCYCLE}] -- 循环
[{CACHE n|NOCACHE}]; -- 缓存
范例:创建一个 s_person 的序列,验证自动增长的操作
CREATE SEQUENCE s_person;
序列创建完成之后,所有的自动增长应该由用户自己处理,所以在序列中提供了以下的两种操作:
nextval :取得序列的下一个内容
currval :取得序列的当前内容
select s_person.nextval from dual;(第一次执行序列值是1,后面每次执行值依次递增)
select s_person.currval from dual;(创建完序列后,首先执行此语句会报错,因为当前序列还没有值)
dual:虚表,只是为了补全语法,没有任何意义。
在插入数据时需要自增的主键中可以这样使用
insert into person(pid, name, sex) values(s_person.nextval, '王五', 2);
在实际项目中每一张表会配一个序列,但是表和序列是没有必然的联系的,一个序列被哪一张表使用都可以,
但是我们一般都是一张表用一个序列,因为每张表的 id 都是独立的。
修改和删除序列:
修改序列:使用 ALTER SEQUENCE 语句修改序列,不能更改序列的 START
ALTER SEQUENCE 序列名称 MAXVALUE 5000 CYCLE;
删除序列:
DROP SEQUENCE 序列名称;
5.Scott 用户下的表结构 默认密码 tiger
-- 解锁 Scott 用户 alter user scott account unlock; -- 解锁 Scott 用户密码(此句也可以用来重置密码) alter user scott identified by tiger;
6.单行函数
1. 字符函数
接收字符输入返回字符或者数值,dual 是伪表
1. 把小写的字符转换成大写的字符
select upper('hello') from dual;
2. 把大写字符变成小写字符
select lower('HELLO') from dual;
3.首字符大写函数
select initcap('hello') from dual;
4.字符串连接函数
select concat('aaa', 'bbb') from dual; -- concat函数在Oracle中参数只能有两个
select 'aaa' || 'bbb' || 'ccc' from dual;
5.字符串截取函数
select substr('helloword', 6) from dual; -- word
select substr('helloword', 6, 1) from dual; -- w
select substr('helloword', -4) from dual; -- word
6.字符串替换函数
select replace('helloword', 'o', '_') from dual; -- hell_w_rd
7.获取字符串长度函数
select length('hello') from dual;
2.数值函数
1. 四舍五入函数:ROUND()
默认情况下 ROUND 四舍五入取整,可以自己指定保留的位数。
select round(25.4343) from dual; -- 25
select round(25.4353, 1) from dual; -- 25.4
2.数值截取函数
select trunc(122.555) from dual t; --默认取整 122
select trunc(122.555,2) from dual t; -- 122.5
select trunc(122.555,-2) from dual t;--负数表示从小数点左边开始截取2位 100
3.取余函数
select mod(10, 3) from dual; -- 1
3. 日期函数
Oracle 中提供了很多和日期相关的函数,包括日期的加减,在日期加减时有一些规律
日期 – 数字 = 日期
日期 + 数字 = 日期
日期 – 日期 = 数字
1. 范例:查询雇员进入公司的周数。雇员进入公司的天数(sysdate – 入职日期) / 7 就是周数
select ename, round((sysdate - hiredate) / 7) from emp;
2. 获得两个时间段中的月数:MONTHS_BETWEEN()
查询所有雇员进入公司的月数
select ename, round(months_between(sysdate, hiredate)) from emp;
3.加月函数 ADD_MONTHS :在当前日期基础上加指定的月
select add_months(sysdate,2) from dual
4.求所在月最后一天 LAST_DAY
select last_day(sysdate) from dual
5.日期截取 trunc
select TRUNC(sysdate) from dual -- 2020-02-21
select TRUNC(sysdate,'yyyy') from dual -- 2020-01-01
select TRUNC(sysdate,'mm') from dual -- 2020-02-01
4.转换函数
TO_CHAR:字符串转换函数
select TO_CHAR(1024) from dual
select TO_CHAR(sysdate,'yyyy-mm-dd') from dual
select to_char(sysdate, 'yyyy-mm-dd hh:mi:ss') from dual; -- 2020-02-21 05:03:48
select to_char(sysdate, 'fm yyyy-mm-dd hh24:mi:ss') from dual; -- 2020-2-21 17:3:50
TO_DATE:日期转换函数
select to_date('1998-04-02', 'yyyy-mm-dd') from dual;
字符串转数字 TO_NUMBER
select to_number('100') from dual
5.通用函数
空值处理nvl
查询所有的雇员的年薪(奖金有null值的用0替代计算)
select ename, sal * 12 + nvl(comm, 0) from emp;
空值处理函数 NVL2
NVL2(检测的值,如果不为 null 的值,如果为 null 的值);
6.条件表达式
case when SQL固有语法,比如在mysql也能用
select t.empno, t.ename, case when t.job = 'CLERK' then '业务员' when t.job = 'MANAGER' then '经理' when t.job = 'ANALYST' then '分析员' when t.job = 'PRESIDENT' then '总裁' when t.job = 'SALESMAN' then '销售' else '无业' end from emp t;
select t.empno, t.ename, case t.job when 'CLERK' then '业务员' when 'MANAGER' then '经理' when 'ANALYST' then '分析员' when 'PRESIDENT' then '总裁' when 'SALESMAN' then '销售' else '无业' end from emp t
Decode函数 Oracle特有函数
select ename, decode(job, 'CLERK', '业务员', 'MANAGER', '经理', 'ANALYST', '分析员', 'PRESIDENT', '总裁', 'SALESMAN', '销售', '无业' ) 职位 from emp;
Oracle数据库字符串除了起别名(起别名也可以不带引号)用双引号,其余都用单引号。
7.多行函数(聚合函数)
1. 统计记录数 count()
select count(1) from emp;
2. 最小值查询 min()
select min(sal) from emp;
3. 最大值查询 max()
select max(sal) from emp;
4. 查询平均值 avg()
select avg(sal) from emp;
5. 求和函数 sum()
select sum(sal) from emp;
8.行列转换
需求:按月份统计 2012 年各个地区的水费,如下图
select (select name from T_AREA where id= areaid ) 区域, sum( case when month='01' then money else 0 end) 一月, sum( case when month='02' then money else 0 end) 二月, sum( case when month='03' then money else 0 end) 三月, sum( case when month='04' then money else 0 end) 四月, sum( case when month='05' then money else 0 end) 五月, sum( case when month='06' then money else 0 end) 六月, sum( case when month='07' then money else 0 end) 七月, sum( case when month='08' then money else 0 end) 八月, sum( case when month='09' then money else 0 end) 九月, sum( case when month='10' then money else 0 end) 十月, sum( case when month='11' then money else 0 end) 十一月, sum( case when month='12' then money else 0 end) 十二月 from T_ACCOUNT where year='2012' group by areaid
需求:按季度统计 2012 年各个地区的水费,如下图
select (select name from T_AREA where id= areaid ) 区域, sum( case when month>='01' and month<='03' then money else 0 end) 第一季度, sum( case when month>='04' and month<='06' then money else 0 end) 第二季度, sum( case when month>='07' and month<='09' then money else 0 end) 第三季度, sum( case when month>='10' and month<='12' then money else 0 end) 第四季度 from T_ACCOUNT where year='2012' group by areaid
9.分析函数
三种排名方式的举例:
(1) RANK 相同的值排名相同,排名跳跃
select rank() over(order by usenum desc ),usenum from T_ACCOUNT
(2) DENSE_RANK 相同的值排名相同,排名连续
select dense_rank() over(order by usenum desc ),usenum from T_ACCOUNT
(3) ROW_NUMBER 返回连续的排名,无论值是否相等
select row_number() over(order by usenum desc ),usenum from T_ACCOUNT
用 row_number()分析函数实现的分页查询相对三层嵌套子查询要简单的多:
select * from (select row_number() over(order by usenum desc) rownumber,usenum from T_ACCOUNT) where rownumber>10 and rownumber<=20
10.集合运算
UNION ALL(并集),返回各个查询的所有记录,包括重复记录
select * from t_owners where id<=7 union all select * from t_owners where id>=5
UNION(并集),返回各个查询的所有记录,不包括重复记录
select * from t_owners where id<=7 union select * from t_owners where id>=5
INTERSECT(交集),返回两个查询共有的记录
select * from t_owners where id<=7 intersect select * from t_owners where id>=5
MINUS(差集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录。
select * from t_owners where id<=7 minus select * from t_owners where id>=5
如果用 minus 运算符来实现分页,语句如下:
select rownum,t.* from T_ACCOUNT t where rownum<=20 minus select rownum,t.* from T_ACCOUNT t where rownum<=10