Oracle(四)

1、常用的数据类型

varchar、varchar2 :表示一个字符串
NUMBER(n):表示一个整数,长度是n
NUMBER(m,n):表示一个任意小数,例如:Number(10,2)--8位整数,2位小数
DATE 表示日期类型(重点掌握)   
CLOB 大对象,表示大文本数据类型,可存4G

BLOB 大对象,表示二进制数据,可存4G

2、再识伪劣(rowid)

回忆:rownum也是一个伪劣,用在分页显示数据条数

select rowid,ename from emp;

结果:


说明:表中的每一行数据都有一个唯一的rowid,那其实我们也可以通过这个唯一的rowid去查询表中的数据。你可以理解为 rowid 像一个指针一样,指向了数据库的文件,这些数据库的文件就是以 .DBF结尾的文件,这些文件在我们Oracle 安装路径下的 D:\app\oradata\orcl 目录里面,这些文件保存的就是表中的数据,那这个rowid 就指向了表中的数据。

作用快速的定位某行具体的数据的位置

select * from emp where rowid='AAAR3sAAEAAAACXAAA';-- 注意不同的电脑此行号可能不一样

相关链接:点击打开链接(rowid的深入详解)

3、利用子查询复制表结构、数据

看下面的sql语句:

create table testtable2 as  select* from testtable ;         --(1)复制表和数据
create table testtable2 as  select* from testtable where 1=1;--(2)复制表和数据--同上
create table testtable2 as  select* from testtable where 1=2;--(3)复制表的定义(结构),不复制数据
insert into testtable2 select * from testtable;              --(4)复制数据---一次插入多条数据(注意!!!)

语法:create table 表1 as select 字段或者部分字段 from 表2 where(逻辑表达式)

具体:where 1=2:表示如果是一个假的条件,那么 testtable2 创建的时候,只要了emp表中的字段,没有要 emp表中的数据

          where 1=1:那么这个testtable2不仅和emp表中的字段一样,并且emp表中的所有数据也复制到了testtable2表中

需求1:我们通过一个查询语句,查出来一些数据(临时表),我想把这些数据保存到一张表中,就可以使用子查询来创建一张表

select e.empno,e.ename,e.sal,e.sal*12 as "年薪",d.dname from emp e,dept d where e.deptno=d.deptno;

说明:上面这条语句查出来的 是一张临时表,我想把这张临时表中的数据 保存到另一张新建的表中,我们就可以用子查询来创建表

create table newTable as select e.empno,e.ename,e.sal,e.sal*12 as "年薪",d.dname from emp e,dept d where e.deptno=d.deptno;
select * from newTable;-- 已经存在数据了

-------------------------

4、修改表中的字段

4.1 加一个字段 alter table 表名 add (字段名 数据类型(长度));   

  alter table newTable add (y varchar(1));-- 注意括号阔上

4.2 改字段(类型)     alter table 表名 modify 旧字段名 新的数据类型;    

alter table testtab modify tname varchar(10);-- 修改字段的名称和数据类型

4.3 除字段       alter table 表名 drop column 字段名  

 alter table testtab drop column sex;

4.4 重命名字段    alter table 表名 rename column 旧字段名 to 新字段名; 

 alter table testtab rename column tname to username;-- 修改字段的名称

5、重命名表名   rename 旧表名 to 新表名;    

 rename testtab to testtable;-- 理解为修改表名

6、删除表          drop table 表名;   

drop table testtable;

补充:使用 drop删除表,并没有真正的删除这张表,这张表还留在数据库的回收站中,可以从回收站中把这张表再还原回来

思考:如何还原呢?具体参见:点击打开链接(工作中)

如何正真的删除表呢

(1)查看回收站  

show recyclebin;

说明:这一串你不认识的东西,就是你刚才删掉的表

(2)清空回收站 

purge recyclebin;

此时回收站中就没有数据了

思路2:直接删除数据不走回收站(英文的含义)

drop table 表名 purge;-- 慎用

扩展:Windows下"shift+delete"可以删除数据不走回收站

需求2:一张表被删除后,你就不能查这张表了,但是你还想差表中的数据怎么办?

思路:可以通过回收站中的表名来查询表中的数据,如下:

select * from "BIN$FpETXCv1R36NfZ1+bN0AJQ==$0"; --注意表名带上双引号,不加双引号查不出来

需求3:从回收站中还原删除的表(闪回技术)

flashback table testtable to before drop;

惊不惊喜,意不意外

思考:比如第一次我先创建一张表 testtable 然后删除,,然后我再创建一张表还叫 testtable 然后再删除,那么这时回收站中有两张同名的表,这时我从回收站中还原一下表:

 flashback table testtable to before drop; -- 请问还原的是哪张表?

说明:还原的是最后一次删除的那张testtable表

需求4:那么问题又来了,我想再还原第一次的那张表,这时会发生两张重名表,那就还原不成功了,怎么办? 

flashback table testtable to before drop rename to testtable2; -- 那就还原时改个名字, 

细节:不是所有的人都有回收站,,没有回收站的人删了还原不了了,不走回收站;管理员登陆(sys)是没有回收站的  

--------------------------

7、约束

    7.1 check 检查性约束    

 create talbe test3(
	tid number,
	tname varcher(20),
	sex varchar(2) check (sex in('男','女')),   --意思就是sex这个字段的值,只能是男或者女,不能是其他值.
	sal number check (sal>0) --检查工资 只能是大于0 不能是0和负值
		   );
    7.2  not null 非空
    7.3  unique 唯一
    7.4 primary key 主键  意思就是非空且唯一

    7.5 foreign key 外键约束

需求5:我们创建一张表把这些个约束都用一下

 create table student(
	sid number primary key,
	sname varchar(32) not null,
	sex varchar(3) check(sex in('男','女')),  --检查性别只能是这两种的一种 比如 工资要大于0  sal number check(sal>0)
	email varchar2(40) unique not null,
	deptno number references dept(deptno) on delete set null -- 关联外键的时候 我们 on delete set null 级联置空
	         );
insert into student values(1,'zhangsan','男','[email protected]',10);-- 插入数据
级联删除的区别
-- 级联删除: on delete casecade 当删除主表中的数据时,相关联的子表数据也一并删除
-- 级联置空 :on delete set null 当删除主表中的数据时,相关联的子表的外键置为null

on delete casecade 的功能是在主数据删除的时候,从属数据一并删除,常用于强耦合关系中。

on delete set null   的功能是在主数据删除的时候,从属数据不会删除,只是将从属数据的关联属性字段设置成NULL,从而变为无主待关联数据,这个常用于弱耦合关系中。

相关链接:点击打开链接

--------------------------

8  数据库的其他对象

    8.1 视图对象

sqlplus sys/123456 as sysdba; -- (1)管理员身份登陆--cmd
show user                     -- (2)显示当前用户是不是管理员
grant create view to scott;   -- (3)授予scott 创建视图的权限

需求6:创建一张视图myview,视图中的数据来自从emp表中的数据(子查询)

create view myview as select * from emp;  

等价说法:把从emp表中的数据查出来,以视图的形式保存

注意:创建视图需要权限,所以我们需要用管理员身份登陆,然后给scott用户 赋予创建视图的权限,scott用户才能创建视图

需求7:只想创建只读视图

create view myview as select * from emp with read only;  -- 创建只读视图,只能查看视图,不能增删改

出发点:视图是一种虚表,视图建立在已有表(基表)的基础上,对于单表可以通过改变视图来影响基表,这不是我们希望的。

视图的本质:视图的创建是要依赖一条子查询语句,将子查询语句查出的数据视图的形式保存

需求8:让视图只能创建、删除、或者替换,但是不能修改

create or replace view  myview as select * from emp where sal>1000; -- create or replace view 创建或者替换视图 如果视图存在就替换

 注意:我们可以通过视图插入数据 更新数据 删除数据 但是不建议这么做;一般情况下我们是不通过视图对表进行增删改操作,我们创建视图是为了查询,不忘初心

    8.2  序列对象 sequence 

        出发点: 为了实现和mysql中 auto_increment自增长的功能(并不仅仅是自增长)

        序列本质:其实是一个数组存储在内存中, 可以提高访问效率  

    看一下创建序列的语法,也就是创建这个数组:

语法:CREATE SEQUENCE 序列名 
	[INCREMENT BY n]                   -- 可选参数 步长 默认值1 每次自增1
	[START WITH n]                     -- 可选参数 起始值 默认是1
	[{MAXVALUE/ MINVALUE n|NOMAXVALUE}]-- 可选参数 最大值和最小值 也可以不定义最大值 NOMAXVALUE
	[{CYCLE|NOCYCLE}]                  -- 循环和不循环  默认值是不循环NOCYCLE  因为循环可能会重复 那么主键是不能重复的,所以选不循环
	[{CACHE n|NOCACHE}];               -- CACHE数组长度  NOCACHE 数组长度不固定

例1:

create sequence myseq9
		increment by 1  -- 步长(相邻两个索引的方差)默认值是1
		start with 1    -- 起始索引值,默认值是 1
		maxvalue 9999   -- 数组的最大索引值
		nocycle         -- 不循环
		nocache;	-- 长度不固定
create sequence myseq10; -- 完成默认的功能

说明:序列创建成功后,有一个指针一样的东西默认在这个序列的第一个数的前一个位置 ,我们可以通过创建好的这个序列中的两个属性:nextval 和  currval 来让指针下移一位和获取指针当前的位置  

需求9:让某个键从1开始自增长

步骤:

(1)我们先让指针往下移动一位

(2)然后我们再查询一下指针的当前位置

(3)接下来我们可以往表中插入值并把序列插入进去即可

相应的SQL语句(可能效率比较高)

-- (1)创建序列
create sequence myseq ;-- 序列创建成功后,有一个指针一样的东西,默认在这个序列的第一个数的前一个位置
-- (2)通过伪表让序列的指针下移一位   
select myseq.nextval from dual;  --显示1(说明移下来了)
-- (3)然后我们再查询一下 指针的当前位置   
select myseq.currval from dual;-- 显示1
-- (4)创建表并向表中插入数据
create table mytable(sid number,sname varchar(20));
insert into mytable values(myseq.currval,'a'); 
insert into mytable values(myseq.nextval,'b');    
insert into mytable values(myseq.nextval,'c');
insert into mytable values(myseq.nextval,'d');
insert into mytable values(myseq.nextval,'e');
insert into mytable values(myseq.nextval,'f');
insert into mytable values(myseq.nextval,'g');
-- (5)显示数据
select * from mytable;

结果(后续补充)

遇到的问题:用Oracle11g创建序列后插入数据的初始值老是从2开始(创建序列后直接通过nextval获取当前的值)

简单解释:Oracle从 11.2.0.1版本开始,提供了一个“延迟段创建”特性:·当我们使用序列作为插入数据时,如果使用了“延迟段”技术,则跳过序列的第一个值。

方式1:更改数据库的“延迟段创建”特性为false(需要有相应的权限)

ALTER SYSTEM SET deferred_segment_creation=FALSE;

方式2(采用):

-- 在创建表时让seqment立即执行;
create table mytable(sid number,sname varchar(20)) SEGMENT CREATION IMMEDIATE;

相关链接:点击打开链接

说明:nextval 和 currval也是两个伪列

    8.3 索引对象 index

理解:  可以理解为一本书的目录或者书签,查询(出发点)起来就比较快

需求10:比如我们要查询emp表中10号部门的员工 

 select * from emp where deptno=10;

分析:我们这张员工表的数据 有10号、20号、30号部门的员工,表中的数据每条数据没有规律,3个部门的员工相互穿插,这样我们在查询10号部门的员工时,得一行一行去挨个查,筛选出10号部门的员工,所以查询起来比较慢 。那我们可以给对这些数据创建一个目录,把3个部门的员工分别归类,10号、20号、30号部门分别归一块,这样分门别类后,可以通过这个索引(目录) 再查询起来就比较快了;那其实这个引里面放的是每条记录的 rowid只不过把这个rowid 分门别类了。

创建索引: on 字段

create index myindex on emp(deptno);-- 针对哪个字段创建的

说明:为emp表中的部门号建立一个索引,这个索引表由Oracle自动维护,我们不用管,然后再查,这样查询效率就高了  

select * from emp where deptno=10;-- 可以测下时间

索引:索引的类型有两种 一种是默认类型 B树索引,另一种是 位图索引(矩阵),相关博客--点击打开链接

    8.4 同义词对象 synonym(不是太懂)

    出发点:方便访问其他用户的对象,可以给其他用户的表、视图起别名

需求11:scott用户要查 hr用户下的表 

-- (1)管理员登陆
sqlplus sys/root as sysdba; 
-- (2) -- 授权 scott 可以查询hr下的employees这张表
grant select on hr.employees to scott 
-- (3)那么scott 才可以去查 hr用户的表(但是还不能为hr.employees起别名--同义词,创建同义词还是需要权限,没有权限会报错)
select count(*) from hr.employees;
-- (4)授权scott用户可以创建同义词对象
grant create synonym to scott;-- 系统账号登陆 
-- (5)然后创建同义词 才能成功
create synonym myhr for hr.employees ;
-- (6)然后我们再查hr.employees 这张表可以通过同义词来查
select count(*) from myhr;

注意:我们默认起的同义词是私有同义词 只有自己能用 你想让别人也能用 可以起公有同义词 通过public 即可

create public synonym myhr for hr.employees ;
未完待续。。。


猜你喜欢

转载自blog.csdn.net/wzj_110/article/details/80516068