Oracle学习笔记

简介

oracle就一个数据库(不同于mysql)

数据库>表空间(用户) > 段 > 区 > 块

表空间>用户>表

1. CMD命令

1.1 数据库启动停止

1.1.1 数据库服务

【计算机>管理>服务】 或者 【win+r >services.msc】启动停止

启动:net start oracleServiceXE // 学习版

停止:net stop oracleServiceXE

OracleServerORCL:必须启动   // 学习版本为OracleServerXE

OracleOraDB21Home1TNSListener:远程访问或plsqldeveloper第三方工具访问,需要启动

OracleOraDB21Home1MTSRecoveryService:

OracelJobSchedulerXE

OracleVssWriteXE

1.1.2 数据库安装卸载

下载安装:

卸载:

(1) 停止oracle所有服务

(2) 应用>oracle>卸载

(3) 删除注册表【win+r > regedit】删除下列所有oracle数据库文件

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\

HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\

(4) 删除环境变量:path

1.2 连接与退出

1.2.1 sqlplus

(1) 登录连接数据

cmd > sqlplus sys as sysdba > 密码   // 系统管理员

cmd > sqlplus  system | 用户名

cmd > sqlplus > 用户名 > 密码

cmd> sqlplus 用户名/密码@主机ip:端口1521/实例名orcl  // 远程连接

用户:sys(最大权限,所有数据库操作权限,只能以sysdba系统管理员权限登录)

用户:system(创建表视图权限)

(2) 退出数据库

exit | quit

1.2.2 pl/sql developer

图形界面工具:安装目录不能有空格

1.3 数据库备份与还原

还原的源文件和目标数据库的表空间,用户,oracle版本,字符集要相同。

备份原因作用:备份恢复,数据迁移

1.3.1 备份文件格式

(1) dmp:二进制文件,跨平台,含权限,效率高,oracle独有

(2) sql:可通过文本编辑器查看,适合小量数据导入导出,表中不能含有blob clob lang等大字段

(3) pde:pl/sql developer 独有

1.3.2 备份(导出)

exp 用户名/密码 [@连接地址:端口号/服务名(orcl)] [file="xxx.dmp"] full=y|owner=用户名|tables=表名,... // 默认文件名 expdat.dmp,端口号默认1521可不写,

注释:full=y(全数据库导出),owner(按用户导出),tables(按表导出)

expdp 用户名/密码 [@连接地址:端口号/服务名(orcl)] directory=预定义文件夹 dumpfile=xx.dmp  full=y|owner=用户名|tables=表名,...

directory:预留文件夹(查询 select *from dba_directories; 创建 create directory xx as 'D:\\xx'; 删除 drop directory xx;)

dumpfile: xx.dmp, 文件名 不能写文件夹路径

nologfile=YES | NO ,不出log文件,默认NO(出)

logfile= xx.log  出Log时的log文件名;

content=data_only | metadata_only | all(默认) 只导数据,表结构,都导

reuse_dumpfiles=YES | NO 是否覆盖已有备份文件,NO(默认不覆盖)

exclude=index (除外对象)

注释:oracle 10g前用exp 10g及之后用expdp, expdp更快,expdp impdp 与 exp imp不能互换使用,expdp只能运行在服务,exp可在服务器与客户端运行。

1.3.3 还原(导入)

注释:表存在会跳过当前表的数据导入,导入前先删除表。报错不影响继续导入。

语法:imp 用户名/密码 [@连接地址:端口号/服务名(orcl)] file=路径文件名.dmp full=y| tables(表名,...) | owner(用户名,...)   // 端口号默认1521可不写,full不写默认为当前用户下对象

(1) 全数据库导出:imp 用户名(system)/密码 full=y [file="xxx.dmp"] 

(2) 按用户导出:imp 用户名(system)/密码 [file="xxx.dmp"] owner=用户名

(3) 按表导出:imp 用户名(system)/密码 [file="xxx.dmp"] tables=表名, 表名

1.3.4 备份(导出expdp)

2. SQL语言

2.1 DCL-用户权限

只有sys和system可以创建表空间,创建用户,权限分配

sys:创建表空间,创建用户,权限分配

system:创建表空间,创建用户,权限分配

对象权限:视图,表,函数,过程

系统权限:创建视图,用户

角色权限:用户权限组

连接权限:...

创建用户:create user 用户名 identified by 密码 defalut tablespace 表空间名; // 用户建在表空间上

授权用户:grant 权限 to 用户名;

权限:dba(管理员), create session(连接登录),create table, create sequence, create view, create procedure, unlimited tablespace(使用永久表空间)

撤销权限:revoke 权限 from 用户名;

通过角色授权用户:角色与用户多对多关系

创建角色:create role 角色名;

授权角色:grant 权限,权限 to 角色名;  // 表空间权限不能给角色

授权角色给用户:grant 角色名 to 用户名,用户名;

撤销角色:revoke 角色名 from 用户;

2.2 DDL-表空间与表

查看实例:select instance_name from v$instance; // 企业版Orcl 简洁版XE, JDBC连接会使用

2.2.1 表空间操作

查看登录用户默认表空间:select tablespace_name from DBA_TABLESPAES

表空间:

SYSTEM:  存sys用户的表,视图,存储过程

SYSAUX: 按照oracle 数据库的实例

UNDOTBS1 存撤销信息

TEMP 用户sql处理表和索引信息

users 用户创建的数据对象

查看指定用户表空间:select default_tablespace, username from dba_users where username='用户名'

创建表空间:create tablesapce 表空间名 datafile ‘文件名.dbf?dbg?’ size 文件大小(30m) [autoexteno on]自动扩容默认不可扩展 [next 256kb]每次扩展大小 [maxsize 2048m]最大容量

设置表空间状态:alter tablespace 表空间 online | offline [normal | temporary | immediate]

online 联机状态, offline 脱机状态  , normal 正常状态,temporary 临时状态 immediate立即状态

设置表空间读写状态:alter tablespace 表空间 read only|write   // only只读 write可读写

重命名表空间: alter tablespace 表空间 rename to 新表空间名

删除表空间:drop tablespace 表空间 [ including contents ] [ cascade constraints ]

[ ncluding, contents ] 同时删除表空间文件

cascade constraints 同时删除表空间完整性

创建大文件表空间:create bigfile tablespace 表空间  datafile 文件名.dbf size 3G

创建临时表空间:create temporary tablespace 表空间 tempfile '文件名.dbf' size 30M

查看临时表空间:select tablespace_name from dba_temp_files

创建临时表空间组:create temporary tablespace 表空间 tempfile '文件名.dbf' size 20M tablespace group 表空间组名

将临时表空间移动到组:alter tablespace 表空间 gourp 表空间组名

查看临时表空间 select *from dba_talbespace_troups

删除临时表空间组 drop tablespace 表空间组名 including contents and datafiles

2.2.2 表操作

表分为,用户表 和 数据字典表(oracle创建维护)

查看表结构:desc 表名;

(1) 创建表:create table 表名(字段 类型 约束)   

快速创建:create table 表名 as select * from 表 where 1>1 ;//根据查询字段创建表,有数据插入数据。

重建表:truncate table 表名; // 不能回滚

删除表:drop table 表名;

修改表名:rename 表名 to 新表名

添加字段:alter table 表名 add(字段 类型 约束, ...)

删除字段:alter table 表名 drop column 字段, 字段;

改字段名:alter table 表名 rename column 字段名 to 新字段名;

改字段属性:alter table 表名 modify(字段 类型 约束, ...);

2.2.3 同义词(oracle专有)

创建私有同义词:create synonym 同义词 for 表名;

查询私有同义词:select * from 用户.同义词;

创建公开同义词:create public synonym 同义词 for 表名;

查询公开同义词:select * from 同义词;

2.3 DML-数据增删改

增删改同mysql一样

插入数据:(字段...) values (..., defaluet, null); 不指定字段 values( defalut和null可不写);

复制数据:insert into 表(字段,...) select * from 表 where 条件;

修改数据:

删除数据:delete [from] 表名 where 条件; // oracle 可以省略from

2.4 DQL-数据查询

2.4.1 查询(select)

字段

distinct去重

字段 as [别名]  // 别名有空格或区分大小写,两侧加双引号

表名 [AS] 别名

伪列

rowid:select rowid, 表别名.* from 表 表别名;

select rowid, 字段, 字段 from 表; //取rowid和*需要给表加别名,或者列出字段名

rownum:查询结果的序号,

2.4.2 查询条件(where)

字符和日期,要包含近单引号之内,

日期默认格式(日-月-年)不能用等于比较,可以用to_char格式化后比较。

where条件

=, != ,<>, > , >=, <, <=, is null, is not null, between and ,in ,not in, like ,not like

逻辑运算 not  and or

any, all, in, exists

满足任意一个, 字段 >any (select ...)

满足全部, 字段 > all (select ...)

存在, where exists (select ...), where 字段 in (select ...)

2.4.3 分组(group by)

查询select之后 跟的一定是 分组字段或聚合函数

having是为了解决where无法写分组聚合函数条件的,所以having后只写聚合函数条件。

2.4.4 排序(order by)

desc 后跟 nulls first|last 指定null值在前或在后。

2.4.5 分页(rownum)

rownum作为条件只支持 <, <=, !=,  不支持>, >=, =, between and, 原因是sql处理完才加number

select * from 

    (select rownum, * from

        (select * from 表 排序)

    )

where rownum 条件;

(1) 最里层,先取得结果,排序

(2) 第二层,将排序的结果,分配行号

(3) 最外层,根据行号过滤条件

注释:执行顺序是,先取得结果,然后分配rownum, 最后排序。

2.4.6 表关联(join)

内联:select * from 表1, 表2 where 条件

外联结:left outer join, right outer join, full outer join

左联(+):select * from 表1, 表2 where 表1.字段=表2.字段(+) // 有空值侧用+表示

右联(+):select * from 表1, 表2 where 表1.字段(+)=表2.字段 // 有空值侧用+表示

using: select * from 表1 join 表2 using(同名字段,...) where 条件; // using内不能用表别名前缀,不能与natural同时使用, using字段是等值联结条件。

natural join:自然连接:select * from 表1 natural join 表2 wher 条件; 两边所有同名字段and连接的条件,不能写on

cross join:交叉联结 笛卡尔积

2.4.7 联合查询(合并查询)

并集:union, union all     (y (y) y)

交集:intersect, 两个结果集相交的部分 (n (y) n)

差集:minus,第一个结果集有,第二个结果集没有的部分 (y (n) n)

2.4.8 嵌套子查询

(1) where 子查询: select * from  表 where 字段 (>,<,=,in,any,all) (select 字段,... from 表)

(2) from 子查询:select * from (select 字段,... from 表)

(3) select 子查询:select 字段, (select 字段 from b where b.字段=a.字段) from 表a;

2.4.9 临时表(with)

伪表dual:select 1 from dual; 

3. 约束

主键,外键,唯一,非空,检查,同mysql一样

非空:列级约束:字段 类型 [constraint 约束名] not null,

非空:modify改约束,添加约束,删除约束

唯一:modify添加,删除, 修正

唯一:定义,表级:constraint 约束名 unique(字段)

主键:同唯一一样

外键:同mysql一样

检查:列级同非空一样

检查:表级

检查:添加约束:同mysql非空追加一样

3.7 序列(sequence)

创建序列:create sequence 序列名;

使用下个序列号:序列名.nextval // 使用后序列值+1

使用当前序列号:序列名.currval  // 使用后序列值不变

创建复杂序列:create sequence 序列名

increment by 递增值  //默认1

start with 开始值  // 默认最小值

maxvalue 最大值

minvalue 最小值

cycle | nocycle  // 循环,不循环

cache | nocache  // 分配到内存,不分配到内存

修改序列:将create 换成alter, 后面一样。只影响生成序列之后的数据,不能改 start with选项

删除序列:drop sequence 序列名;

4. 事务与锁

事务控制语言 tcl

4个特性:同mysql一样

原子性:更新删除,都执行,都不执行。都成功,或都失败

一致性:执行后,与数据库数据保持一致。

隔离性:不受其他事务影响,不能多个事务处理同一个数据

持久性:提交后,数据永久改变。

4.1 事务提交方式

显示事务:手动提交 dml

隐式事务:自动提交 ddl,dcl

设置事务保存点:savepoint 保存点名;//回滚点

回滚到保存点: rollback to 保存点名; //回滚点

并发问题:脏读,非重复性读取,幻读,丢失更新(1更新,2更新,丢失1更新)

5. 索引

创建索引:同mysql

建表时根据主键自动创建索引

唯一索引,联合索引,同Mysql

5.4.1 索引优化原则

(1) 固定值查询:联合索引,最左前缀不在where条件中

(2) 范围查询:大于等于,小于等于,代替 大于,小于

(3) 函数查询:索引字段加函数,索引失效

(4) 模糊查询:值前模糊索引失效

(6) 类型转换:字符串字段,不加引号索引失效

not(in,like,exists) 索引失效

不等于 索引失效

is null, is not null 索引失效

from两个表,用最后一个表的索引先使用,同级别 主键>唯一>常规

where 条件中 在前的索引优先使用,同级别 主键>唯一>常规

6. SQL优化

6.1 SQL性能分析

(1) pl/sql developer查看执行计划

设置:tools/preference/windows type/plain window

查看:选中sql > tools > explain plan  // 选中sql > F5

执行顺序:最里面的先执行,同层上面的先执行

表的访问方式:

table access full 全表扫描

table access by index rowid 通过磁盘地址扫描

table access by index scan 索引扫描

  index unique scan 主键或唯一扫描

  index range scan 索引范围扫描,范围条件,非唯一索引

  index full scan 全索引,全表扫描通过索引直接取到数据(覆盖索引)

  index fastfull scan 全索引,结果不排序的全索引扫描

  index skip scan 索引跳跃,使用组合索引,除了第一个索引字段。

object owner 所在当前用户

object name 当前表名

cost 代价值,越低越好。

6.2 SQL性能优化

(1) from 多个表

表1,2万数据,表2,1条数据,

select count(*) from A2,A1; // 26秒

select count(*) from A1, A2; //1秒

注释:数据少的表放后面,from最后的表先执行

(2) where 条件

多表连接条件,写在过滤条件之前。

低效:select * from A1, A2 where A1.xx=1 and A1.xx=A2.xx;

高效:select * from A1, A2 where A1.xx=A2.xx and A1.xx=1;

(3) select * 改为 select 字段,*需要转换成字段名,更耗时。

(4) exists 比 in效率高 一点点,not in(oracle 10g)前效率最低,改进后也不如not exists

(5) 表关联 比 exists效率高,子查询用主表值做条件

(6) 1条 连 多条,取1条,用exists替代distinct

(7) 同字段不同值,查询2次,比in效率低2倍

(8) union 去重排序,没有重复数据用union all效率高

(9) decode优化一个字段不同值的count

低效:select count(1) from A where a=1; select count(1) from A where a=2;

高效:select count(decode(a,1,1,null)), count(decode(a,2,1,null)) from A

(10)1连多分组查询,用1连分组后的从表。

(11) 避免使用排序,必须用则加索引

(12) where 条件不写到having中

(13) 表关联多了影响效率,尽量不超过3个,包括子查询。

(14) insert into ... select 占用内存,300万以下数据可使用。

7. 视图

查看视图定义:desc 视图名, describe 视图名

创建视图:create [or replace] view 视图名 as select ...

检查选项:create view 视图名 as select ... with read only 只读,with check option 不能插入更新不满足where条件的数据

删除视图:drop view 视图名;

使用视图:select * from 视图名;

视图更新数据:update 视图 set 字段=值..

创建错误视图:create view force 视图名 as select ...; // 基表不存在

多表联合,改视图数据:只可改键保留表,单条数据主表?

分组创建的视图,不能更新数据。

物化视图:未了解

8. PL/SQL

8.1 变量

8.1.3 局部变量

声明:declare 变量名 类型(长度); 变量名...

基于表的数据列定义:变量名 表名.列名%type;

设置:变量名 := 值

select 字段 into 变量名 from 表名;// select into 只能是一条记录。多条或无数据会异常

变量:变量名 类型 [:= 值];

常量:常量名 constant 类型(长度) := 值;

对象行:变量名 表名%ROWTYPE;

自定义:TYPE 类型名 IS RECORD( 名 类型, 名 类型);

变量名 自定义类型;

8.2 分歧条件

if 条件 then ... [elseif 条件 then ...] [else ...] end if; // else没有处理写null,不能不写?

case 字段 when 值 then ... else ... end case;

case when 表达式 then ... else ... end case;

8.3 循环

8.3.1 loop

loop 
  处理
  exit when 条件;
  处理
end loop;

8.3.2 while

while 条件 loop
  处理
end loop;

8.3.3 for

for 变量(不用声明) in 初值.. 终值 loop
  处理...
end loop;

8.4 游标

游标是一个系统缓冲区,用于存放查询结果集。

声明游标:declare cursor 游标名 is select * from 表;// 与变量共用一个declare

声明游标:declare cursor 游标名 is 查询语句

打开游标:同Mysql

读游标,关闭游标:同 Mysql

declare
  cursor 游标名 is select...;
  变量 类型;
begin
  open 游标;
  loop 
    fetch 游标 into 变量;
    exit when 游标%notfound;
  end loop;
  close 游标;
end;
declare
  cursor 游标(参数 [in] 类型) is select ... where 字段=参数;
begin
  for rec in 游标(参数) loop
    fetch ...
  end loop;
end;

 动态游标

TYPE 行类型 IS REF CURSOR;

行变量 行类型;

VSQL := 'select * from ' || 参数名 || 'where ...';

OPEN 行变量 FOR VSQL;

loop

  fetch 游标名 into 行变量?

8.5 过程化SQL

declare 变量 类型 ...;

begin  //开始

  处理...

exceptin

  异常处理

end

8.6 存储过程

可返回多个值

参数:in, out, in out.// in不可赋值,类型不可写长度

创建:create procedure 过程名 as begin ... 同Mysql

调用过程:execute 过程名  //简写 exec 过程名

查看创建语句:select * from user_source where name=过程名

有参过程:create procedure 过程名(参数名 in 类型) as ...

修改过程:create or replace procedure 过程名 as ...

删除:同Mysql

8.6.1 创建存储过程

create [or replace] procedure 存储过程名(参数 类型, 参数 out 类型)
is | as
  变量 类型
begin
  ... insert, update;
  commit;
exception
  异常处理...
end [过程名];

8.6.2 调用存储过程

call 过程名(参数...);

有传出参数,不能用call调用存储过程。

declare 传参变量

begin

  过程名(参数, ..., 传参变量);

end;

8.6.3 jdbc调用存储过程

CallableStatement st = con.prepareCall("{call 过程名(?,?,?)}");

st.setString(1, xxx);

st.registerOutParameter(1, OracleTypes.Numvberr); // 注册返回值类型,没有返回值不用写

st.execute();

st.getString(1); // 获取传出参数

8.7 存储函数

存储函数普遍用于查询,可在select中使用

(1) 创建存储函数

create [or replace] function 函数名(参数 类型,...)
return 类型
is 
  变量 类型;
begin
  处理...
  return 结果;
exception
  异常处理...
end [函数名];

(2) 调用存储函数

select 函数名(参数) from dual;

8.8 触发器

创建:同Mysql,oracle没有for each row 语法?

删除:同mysql

修改:create or replace trigger 触发器名 ...

查看触发器列表:select OBJECT_NAME from user_objects where object_type ='trigger';

查看触发器创建语句:select * from user_source where name='触发器名' 

(1) 创建触发器

create [or replace] trigger 触发器名
before|after insert|update|delete [of 列名]  
//增删改可用or连接,修改可指定列名处罚,多列逗号分割
on 表名 [for each row] [when 条件]
// 行级触发器 row, 和语句级触发器
declare 
  ...
begin
  // 伪记录变量
  // new.字段,old.字段,可以取值
  // new.字段:=值,old.字段:=值, 在before中使用可以改变更新前的值。
  ...
end;

8.9 异常处理

8.9.1 预定义异常

共21种

NO_DATA_FOUND // 使用select into 没有结果

TOO_MANY_ROWS // 使用select into 返回多条结果

其它:略

8.9.2 自定义异常

8.9.3 异常使用

写在begin end之间

declare 变量...;

begin

  处理...

  commit;

exception

  when 异常类型(NO_DATA_FOUND) then

    异常处理

  when others then

    其它异常处理

  rollback;

end

8.10 读写文件

(1) 写文件

NFNC:= UTL_FILE.FOPEN('D:', '文件名', 'W', 3000);

UTL_FILE.PUT(NFNO, '内容');

UTL_FILE.NEW_LINE(NFNO, 1);

UTL_FILE.FCLOSE(NFNO);

(2) 读文件

NFNO:=UTL_FILE.FOPEN('D:', '文件名', 'R', 3000);

LOOP BEGIN

  UTL_FILE.GET_LINE(NFNO, VDATA);

EXCEPTION

  WHEN NO_DATA_FOUND THEN EXIT;

END;

END LOOP;

UTF_FILE.FCLOSE(NFNO);

9. 函数

聚合函数,count, sum, max, min

数值函数:

向上取整:ceil(值)

向下取整:floor(值)

向0取整:trunc(值, 保留小数位数)  //多余小数舍弃  

四舍五入:round(n) 取整数判断第一位小数, round(n, s) s保留小数位数判断s+1

字符函数:

拼接:concat(s1, s2); //双竖线||也可拼接

补齐:lpad(s1, len, pad) // rpad(s1,len,pad)

去空:trim(s) ltrim, rtrim

截取:substr(s1, start1, len) 从s1的start1位置(最小1)开始截len个字符

截掉:

取长:length(s1) //

替换:replace(s1,s2,s3)将s1中的s2换为s3 

日期函数:

当前日时sysdate,

当前时间systimestamp

当月最后一天last_day(sysdate)

计算(加月):add_months(日期, 值)

截取日期:trunc(sysdate) //得到日期(年月日)

trunc(sysdate, 'mm') // 保留月,截掉日,返回当月1日

trunc(sysdate, 'yyyy') // 返回当年,1月1日

注释:指定hh,mi返回为0时间,不能指定ss秒

转换函数

数值-字符 to_char(1.23) => '1.23' , to_char(1.23, '9.9') => '1.2' // 等价与 数值||''

字符-数字 to_number('1.123', '999.999) => 1.123

字符-日期 to_date('1999-12-31', 'yyyy-mm-dd')

日期-字符

to_char(sysdate, 'yyyy-mm-dd') // 不能转成汉字格式,需要手动拼接

to_char(systimestamp, 'yyyy-mm-dd hh:mi:ss')

流程控制函数:

nvl(字段, 值)  // 判断字段,为null,则转换成指定值,值与字段类型要一致

nvl2(字段,真值,假值)  // 判断字段,

nullif(字段, 值) // 等同nvl

decode(字段, [检测值, 返回值, ...], 缺省值) //参数为偶数个,最后值为缺省值,简化case表达式

coalesce(字段, 值, 值...) 返回第一个不为null的值。

case 字段 when 值 then ... else ... end

case when 表达式 then ... else ...end

数据类型

数值:number(m [, n])  // m(1-38)  n(-184-127)  ,m有效数字位数总长,n小数位数,不指定m默认18

integer 相当于 number(38, 0) 插入小数四舍五入

字符:CHAR(12 BYTYE)//字节定长补空,CHAR(12 CHAR)// 字符定长补空, nchar, VARCHAR2 //变长统一编码字符 (4000字符), nvarchar // 变长非统一编码字符  long(0-2G)

char 定长,默认1,最大2000字节

varchar2 变长,最大4000字节,可指定字节长度

nvarchar2 含unicode最大4000字节,可指定字符长度。

long 大文本,最多2g字节

日期:

中文版和英文版格式不同

DATE 'YYYY-MM-DD hh:mm:ss' 日期时间,精确到秒
TIMESTAMP 'YYYY-MM-DD hh:mm:ss.sss 精确到秒后9位

当前系统时间 SYSDATE

插入sysdate 默认格式(01/3月/2019) 通过to_date(sysdate, 'yyyy-MM-dd')转换格式,

二进制:

clob 存字符最多4g

blob 存二进制(图形,声音,视频)最多4g

你可能感兴趣的:(oracle,数据库)