Oracle基础

1.数据类型

数据类型 类型字符 说明
CHAR() 字符型 固定长度字符串,最大长度是2000字节
NVARCHAR2() 可变长度字符串,最大长度是4000字节
VARCHAR2()
NUMBER 数值型 数值类型,可包含小数
DATE 日期类型 日期/时间

需要注意的是,在oralce中使用当前的时间,可使用关键字sysdate,mysql就不同了,它需要使用函数,即sysdate()。

2.表的操作

表的操作(表及数据的增删改查)和mysql类似,详见https://www.cnblogs.com/zys2019/p/11567312.html#_label2_0。不过需要注意的是,oracle并没有mysql的limit分页查询,而是有它自己的分页方式。

2.1分页查询

oracle分页使用rownum关键字。用法如下:先假如有一个员工表emp

--查询员工信息的前5条数据 第一页数据

select rownum r,e.* from emp e where rownum <=5

--查询员工信息的6-10条数据 第二页数据

 select rownum,t.* from (select rownum r,e.* from emp e where rownum <=10) t where r>5

分页规律总结:每页显示m条数据,查询第n页数据

 select * from (select rownum r,e. * from 要分页的表 e where rownum<=m*n) t where r>m*n-m

2.2 给表和列添加注释

1)给表添加注释

comment on table 表名  is  '注释';

2)给列添加注释

comment  on  column  表名.字段名   is  '注释';

2.3添加列

当在表创建后,需要给表添加列。下面语句是给t_user表添加列addr,类型是字符串,长度200:

alter table t_user add addr NVARCHAR2(200);

 

3.视图

3.1定义

视图是一个虚拟的表,它在物理上并不存在。视图可以把表或其他视图的数据按照一定的条件组合起来,但它并不包含数据,它只是从基表中读取数据。查询视图,本质上是对表进行关联查询。可以将复杂的查询创建成视图,提供给他人使用,他人就不需要去理解其中复杂性的业务关系或逻辑关系,使用比较多的地方是关联查询等。

3.2视图的基本操作

数据准备:执行的sql如下:

CREATE TABLE DEPT ( id NUMBER, demp_name VARCHAR2 ( 25 ), PRIMARY KEY ( id ) );
CREATE sequence seq_dept;
INSERT INTO DEPT
VALUES
    ( seq_dept.nextval, '财务部' );
INSERT INTO DEPT
VALUES
    ( seq_dept.nextval, '人事部' );
INSERT INTO DEPT
VALUES
    ( seq_dept.nextval, '信息部' );
CREATE TABLE EMP ( id NUMBER, name VARCHAR2 ( 255 ), phone VARCHAR2 ( 20 ), dept_id NUMBER, PRIMARY KEY ( id ) );
CREATE sequence seq_emp;
INSERT INTO EMP
VALUES
    ( seq_emp.nextval, '张三', '15625456352', 1 );
INSERT INTO EMP
VALUES
    ( seq_emp.nextval, '李四', '15825457552', 2 );
INSERT INTO EMP
VALUES
    ( seq_emp.nextval, '王五', '15925456354', 3 );
INSERT INTO EMP
VALUES
    ( seq_emp.nextval, '李六', '15925456444', 1 );

现要查询员工编号和部门的名称,语句如下:

select emp.id,dept.demp_name from emp,dept where emp.dept_id=dept.id

3.2.1创建视图

语法:or replace表示视图存在就修改,不存在就创建

create or replace view 视图名
as
select 语句;

示例:

create or replace view v_emp_dept
as
select emp.id,dept.demp_name from emp,dept where emp.dept_id=dept.id;

3.2.2修改视图

修改视图,增加员工的姓名信息。使用关键字or replace。

create or replace view v_emp_dept
as
select emp.id,dept.demp_name,emp.name from emp,dept where emp.dept_id=dept.id;

3.2.3删除视图

删除上述创建的视图

drop view v_emp_dept

3.2.4使用视图

把视图创建成功后,就可以直接使用视图,使用方式很简单,就把视图看作一个表即可。

select * from view v_emp_dept

4.索引

4.1定义

 索引在表中的作用,相当于书的目录对书的作用,可以提高 SQL 语句执行的性能。

4.1.1索引类型

索引分为B树索引和位图索引。

(1)B树索引。B树索引 又可以进行细化,如下图:

1)唯一索引:唯一索引确保在定义索引的列中没有重复值,但可以不限制NULL值。 Oracle 自动在表的主键列上创建唯一索引,使用CREATE UNIQUE INDEX语句创建唯一索引。

2)组合索引:组合索引是在表的多个列上创建的索引,索引中列的顺序是任意的如果 SQL 语句的 WHERE 子句中引用了组合索引的所有列或大多数列,则可以提高检索速度。

3)反向键索引:反向键索引反转索引列键值的每个字节,为了实现索引的均匀分配,避免b树不平衡通常建立在值是连续增长的列上,使数据均匀地分布在整个索引上。创建索引时使用REVERSE关键字。

(2)位图索引

位图索引适合创建在低基数列上,位图索引不直接存储ROWID,而是存储字节位到ROWID的映射,节省空间占用。如果索引列被经常更新的话,不适合建立位图索引。总体来说,位图索引适合于数据仓库中,不适合OLTP中。

4.2索引的基本操作

数据准备,执行是脚本如下:

create table student(
    id NUMBER,
    name VARCHAR2(20),
    age NUMBER,
    ID_card VARCHAR2(20),
    addr VARCHAR2(200),
    PRIMARY KEY(id)
);
create sequence seq_stu;
insert into student values(seq_stu.nextval,'李敏',20,'4203251112','湖北十堰');
insert into student values(seq_stu.nextval,'赵航',30,'4203251532','湖北武汉');
insert into student values(seq_stu.nextval,'刘敏',25,'4203258946','湖北武汉');
insert into student values(seq_stu.nextval,'李慧',16,'4203254525','湖北宜昌');

4.2.1创建索引

基本语法:

create index 索引名 on 表名(列名);

1)创建唯一索引

create unique index index_id_card on student(ID_card);

2)创建组合索引

创建姓名和地址的组合索引

create index index_stu_name_addr on student(name,addr);

4.2.2修改索引

 修改索引主要是修改索引的名字。修改组合索引的名字

alter index index_stu_name_addr rename to index_name_addr;

4.2.3删除索引

语法:

drop index 索引名称

删除创建的组合索引

drop index index_stu_name_addr;

5.序列

5.1定义

序列的作用是自动生成整型数值,作为一个记录的唯一标识,相当于id的自增。它最多由38个数字组成。

5.2序列的基本操作

5.2.1创建序列

语法:

create sequence 序列名
minvalue 1
nomaxvalue
start with 1
increment by 1
nocycle
cache 20

参数说明如下:

minvalue 1:序列的最小值是1

nomaxvalue:序列无最大值限制

start with 1:序列的初始值是1

increment by 1:序列的间隔是1

cache 20:高速缓存大小是20

以上的参数都有默认值,也就是后面的这些数值,如果没有特定的要求,那么创建序列就可以简写,命令如下:

create sequence seq_user_id;

5.2.2修改序列

修改序列的步长是2

alter sequence seq_user_id increment by 2

5.2.3删除序列

drop sequence seq_user_id;

5.2.4使用序列

创建完序列后,它虽然是自增的,但是要往表里插入值,就必须使用序列

1)使用序列的下一个值

语法:

序列名.nextval

示例1:查询序列的下一个值

select seq_user_id.nextval from dual;

示例2:插入记录,保存id自增

insert into user(id,name) values(seq_user_id.nextval,'张三');
insert into user(id,name) values(seq_user_id.nextval,'李四');

2)使用序列的当前值

语法:

序列名.currval

示例:查询序列的当前值,必须是先执行查询序列下一个值才可以查询得到序列当前值

select seq_user_id.currval from dual;

5.3修改序列的起始值

假设有一个序列seq_user现在的值是15,想把序列的起始值改为1000,下次使用的值是1001,那么做法如下

1)修改序列的步长

由于要从15变成1000,那么步长就是1000-15=985,则修改序列的步长是985

alter sequence seq_user increment by 985;

2)查询序列的当前值

查询一次序列后,序列的值就发生了变化,已经到达了1000

select seq_user.nextval from dual;

3)重置序列的步长为1

alter sequence seq_user increment by 1;

6.函数

6.1定义

Oracle创建函数是通过PL/SQL自定义编写的,通过关键字function按照自己的需求把复杂的业务逻辑封装进PL/SQL函数中,函数提供一个返回值,返回给使用者。

6.2函数的基本使用

6.2.1 find_in_set在oracle下的解决方案

先有一张表user,数据如下:

编号 姓名 爱好(0打篮球,1踢足球,2打乒乓球,3跑步,4玩游戏)
1 张三 1,3
2 李四 0,2,4
3 王五 0,1,3
4 赵柳 1,2,3,4

现在需求是查询出爱好是跑步的用户信息,mysql可直接通过find_in_set进行查询,但是oracle并没有这个函数。

mysql查询:

select * from user where find_in_set('3',爱好);

虽然oracle没有这个函数,但是可以自定义这个函数,即自己创建函数后再使用。创建函数的sql如下:

create or replace function find_in_set(arg1 in varchar2,arg2 in varchar)
return number is Result number;
begin
select instr(','||arg2||','  , ','||arg1||',') into Result from dual;
return(Result);
end find_in_set;

创建之后直接使用这个函数

select * from userwhere find_in_set('3',爱好)!=0

如果需要删除函数,语法是:

drop function 函数名;

7.case when的使用

7.1表达式

 oracle中CASE WHEN 表达式有两种形式:

--简单Case函数  
CASE sex  
WHEN '1' THEN ''  
WHEN '2' THEN ''  
ELSE '其他' END  

--Case搜索函数  
CASE
WHEN sex = '1' THEN ''  
WHEN sex = '2' THEN ''  
ELSE '其他' END  

第一种方式比较简便,推荐使用第一种。

7.2用法

CASE WHEN 在语句中不同位置的用法

1)用在select查询结果中(最常用)

select name,age,
case sex 
when '1' then '男'
when '2' then '女'
else '未知' end sex
from student

2)用在where条件中

用在where条件中,主要是用来同时满足或不同时满足的情况。

SELECT t2.*, t1.* FROM t1, t2
WHERE (
CASE WHEN t2.COMPARE_TYPE = 'A' AND t1.SOME_TYPE LIKE 'NOTHING%' THEN 1
     WHEN t2.COMPARE_TYPE != 'A' AND t1.SOME_TYPE NOT LIKE 'NOTHING%' THEN 1
     ELSE 0
     END
) = 1

3)用在group by分组中

在grouy中用的比较少,需要结合select的case when使用

SELECT  
CASE WHEN salary <= 500 THEN '1'  
WHEN salary > 500 AND salary <= 600  THEN '2'  
WHEN salary > 600 AND salary <= 800  THEN '3'  
WHEN salary > 800 AND salary <= 1000 THEN '4'  
ELSE NULL END salary_class, -- 别名命名
COUNT(*)  
FROM    Table_A  
GROUP BY  
CASE WHEN salary <= 500 THEN '1'  
WHEN salary > 500 AND salary <= 600  THEN '2'  
WHEN salary > 600 AND salary <= 800  THEN '3'  
WHEN salary > 800 AND salary <= 1000 THEN '4'  
ELSE NULL END;  

8.oracle恢复删除的数据

8.1通过时间恢复

1)查询当前系统时间

select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

2)查询删除数据的时间点的数据

select * from 表名 as of timestamp to_timestamp('2020-05-29 15:29:00','yyyy-mm-dd hh24:mi:ss');

3)恢复删除且已提交的数据

flashback table 表名 to timestamp to_timestamp('2020-05-29 15:29:00','yyyy-mm-dd hh24:mi:ss');

如果在执行上面的语句,出现错误。可以尝试执行下面的命令来允许更改时间戳:

alter table 表名 enable row movement; 

8.2通过scn恢复

1)获得当前数据库的scn号:需要切换到sys用户或system用户

select current_scn from v$database; 

查询到的scn号为:1499223

2)查询当前scn号之前的scn

select * from 表名 as of scn 1499220;

确定删除的数据是否存在,如果存在,则恢复数据;如果不是,则继续缩小scn号

3)恢复删除且已提交的数据

flashback table 表名 to scn 1499220;

 

posted @ 2020-07-09 21:11  钟小嘿  阅读(218)  评论(0编辑  收藏  举报