【oracle学习】5.创建和管理表
2016-08-30 09:06
483 查看
还是先介绍一下我们要用到的两张表以及数据:
员工信息表
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
--------------- -------------------- ------------------ --------------- -------------- ----- ----- ---------------
1110 张三 主管 1110 12-3月 -14 5200 0 20
1111 李四 销售 1116 03-11月-15 3400 500 30
1112 王五 销售 1116 25-4月 -12 4400 800 30
1113 赵二 后勤 1110 30-5月 -11 3450 0 40
1114 李磊磊 会计 1110 22-12月-15 2500 0 50
1115 张少丽 销售 1110 11-3月 -16 2400 1400 30
1116 林建国 主管 1116 22-1月 -16 5700 0 20
1117 马富邦 后勤 1116 22-7月 -13 2800 0 40
1118 沈倩 会计 1116 06-5月 -10 2100 0 50
部门表
DEPTNO DNAME
-------- --------
20 管理部门
30 销售部门
40 后勤部门
50 金融部门
接下来我们探讨在oracle中如何创建和管理表的技巧
(1)设置适当的默认值
首先我们创建一个测试表:
这里我们创建了三个字段,id、姓名和雇用日期。其中雇佣日期默认是系统当前时间。
我们为词表增加一条数据:
insert into test1(tid,tname) values(1,'jack');
然后取出看一下结果:
select * from test1;
TID TNAME HIDATE
---------- ---------------------------------------- --------------
1 jack 28-8月 -16
可以看到,当我们没有填写日期的时候,我们的雇佣日期刚好是系统的当前时间。
(2)从其他表中获取数据建立新表
我们创建一个新表emp20,其中的数据要求是emp雇员信息表中部门为20的所有雇员的信息:
create table emp20 as select * from emp where deptno=20;
然后我们查看一下,果然就是部门为20的雇员信息:
select * from emp20;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- -------------------- ------------------ ---------- -------------- ----- ----- ----------
1110 张三 主管 1110 12-3月 -14 5200 0 20
1116 林建国 主管 1116 22-1月 -16 5700 0 20
我们只拷贝表结构的时候,在where语句后面加上一个用不成立的条件就可以了(如1=2)。
(3)快速建表
创建一个收入表,其中含有:员工号、姓名、月薪、年薪、部门名称
不难发现,有一些数据我们可以从emp表和deptno里取出,但是有一些
数据(如年薪和部门名称)我们需要间接总结取出,还要给新的字段赋别名:
创建完成后,我们查看一下我们创建的新表:
select * from empincome;
EMPNO ENAME SAL ANNLSAL DNAME
---------- -------------------- ----- ------- -----------
1110 张三 5200 62400 管理部门
1111 李四 3400 40800 销售部门
1112 王五 4400 52800 销售部门
1113 赵二 3450 41400 后勤部门
1114 李磊磊 2500 30000 金融部门
1115 张少丽 2400 28800 销售部门
1116 林建国 5700 68400 管理部门
1117 马富邦 2800 33600 后勤部门
1118 沈倩 2100 25200 金融部门
这样我们就快速创建出一个员工的收入表,而且数据我们也都迁移过来了。
注意,之前我们说过一个rownum,是行号:
select rownum,ename from empincome;
ROWNUM ENAME
---------- --------------------
1 张三
2 李四
3 王五
4 赵二
5 李磊磊
6 张少丽
7 林建国
8 马富邦
9 沈倩
其实还有一个rowid,为行地址,可以唯一确定表中某行的位置:
select rowid,ename from empincome;
ROWID ENAME
------------------ --------------------
AAADnQAAEAAAAEcAAA 张三
AAADnQAAEAAAAEcAAB 李四
AAADnQAAEAAAAEcAAC 王五
AAADnQAAEAAAAEcAAD 赵二
AAADnQAAEAAAAEcAAE 李磊磊
AAADnQAAEAAAAEcAAF 张少丽
AAADnQAAEAAAAEcAAG 林建国
AAADnQAAEAAAAEcAAH 马富邦
AAADnQAAEAAAAEcAAI 沈倩
(4)修改表的多种方法
看清楚,是修改表结构,不是修改表中的数据!
修改表有以下方式:
追加新列(add) 修改列(modify) 删除列(drop) 重命名列(rename)
我们首先看一下我们test1表的表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(20)
HIDATE DATE
接下来我们给该表新增一列photo,格式为blob,可存储二进制流的格式:
alter table test1 add photo blob;
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(20)
HIDATE DATE
PHOTO BLOB
如果嫌tname的长度太短,我们可以修改其数据类型,给其增加长度:
alter table test1 modify tname varchar2(40);
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(40)
HIDATE DATE
PHOTO BLOB
我们可以使用drop将刚刚的photo字段删除:
alter table test1 drop column photo;
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(40)
HIDATE DATE
最后,我们修改一下我们的tname,使其更名为username:
alter table test1 rename column tname to username;
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
USERNAME VARCHAR2(40)
HIDATE DATE
(5)删除表
我们先看一下,当前操作员表空间下的所有表:
select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------------------------------------ -------------- ----------
TEST1 TABLE
EMP02 TABLE
TESTSAVEPOINT TABLE
EMP20 TABLE
EMPINCOME TABLE
EMP TABLE
BIN$PIFbfASsQ/azoeQueDQvqw==$0 TABLE
DEPT TABLE
PROCEDURE_TEST TABLE
我们删除EMP02这张表
drop table EMP02;
我们删除的表都可以在oracle的回收站中看到。
①查看回收站
show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
DEPT BIN$PIFbfASsQ/azoeQueDQvqw==$0 TABLE 2016-08-21:11:09:58
EMP02 BIN$FyCatp18TrCgnxnv8Fr07g==$0 TABLE 2016-08-28:10:16:35
可以看到我们刚刚删除的表。
②清空回收站
purge recyclebin
SQL>回收站已清空。
如果我们想彻底删除表,也就是不安放在回收站中,可以使用purge语句:
drop table test1 purge;
执行之后我们去回收站看是没有test1这张表的删除数据的。
(6)给表加约束
我们创建一个测试表,含有id、姓名、性别和薪水。其中性别我们做了约束,只能是
“男”或“女”,添加的薪水必须大于0。
我们首先添加一条正常的数据:
insert into test2 values(1,'Tom','男',1000);
select * from test2;
TID TNAME GENDER SAL
---------- ---------------------------------------- -------- -----
1 Tom 男 1000
插入成功。
然后我们插入一条数据,让其性别为“哈”:
insert into test2 values(1,'jack','哈',1000);
然后发现报错了:
insert into test2 values(1,'jack','哈',1000)
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (JACK.SYS_C004067)
同样的,我们把薪水设置成小于0的:
insert into test2 values(1,'jack','男',-1000);
也会报错
insert into test2 values(1,'jack','男',-1000)
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (JACK.SYS_C004068)
注意,两次报错的约束条件代号是不一样的(JACK.SYS_C004067和JACK.SYS_C004068)。
上面我们定义的约束仅仅是“检查列值是否满足一个布尔表达式(CHECK)”
数据库通常拥有以下约束:
实体完整性有primary key (主键)
参照完整性有foreign key (外键)
用户自定义完整性有:列表非空(NOT NULL),列表唯一(UNIQUE),
检查列值是否满足一个布尔表达式(CHECK)
前三个的约束我们要通过constraint关键字来实现。
我们创建一个myperson表,使其拥有主键pid,pname不为空,gender只能是“男”和“女”,
email是唯一的,deptno是emp表的外键。
提示:对于ON DELETE CASCADE
这是数据库外键定义的一个可选项,用来设置当主键表中的被参考列的数据发生变化时,
外键表中响应字段的变换规则的。update则是主键表中被参考字段的值更新,delete是指在主键表中删除一条记录。
on update 和 on delete 后面可以跟的词语有四个
no action , set null , set default ,cascade
no action 表示 不做任何操作,
set null 表示在外键表中将相应字段设置为null
set default 表示设置为默认值
cascade 表示级联操作,就是说,如果主键表中被参考字段更新,外键表中也更新,主键表中的记录被删除,外键表中改行也相应删除。
此时我们发现报错
deptno number constraint myperson_FK references dept(deptno) ON DELETE CASCADE
*
第 6 行出现错误:
ORA-02270: 此列列表的唯一或主键不匹配
原因是我们没有给之前的dept表创建主键:
desc dept;
名称 是否为空? 类型
----------------- -------- ------------
DEPTNO NUMBER
DNAME VARCHAR2(50)
外键一定要是另一张表的主键,所以这里我们修改一下dept表,使其deptno为主键:
alter table dept modify deptno number constraint dept_PK primary key;
SQL>表已更改。
然后我们看一下dept表结构:
desc dept;
名称 是否为空? 类型
----------------- -------- ------------
DEPTNO NOT NULL NUMBER
DNAME VARCHAR2(50)
此时deptno已经是表dept的主键了。
我们再次执行上面的建表语句,我们就创建成功了。
注意,我们上面加的“myperson_XXX”,是一个约束的名字,当出现错误的时候,就会报该
约束的名称,这样使用这个表的其它人就明白自己插入的数据哪里不合适了。
例如我们还是将插入的数据的性别设置成“哈”:
insert into myperson values('p001','jack','哈','jack@126.com',20);
发现报错:
insert into myperson values('p001','jack','哈','jack@126.com',20)
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (JACK.MYPERSON_GENDER)
可以看到,我们违反了jack用户表空间下名为myperson_gender的约束(性别约束),一目了然。
转载请注明出处:http://blog.csdn.net/acmman/article/details/52366264
员工信息表
create table EMP( EMPNO NUMBER, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER, HIREDATE DATE, SAL BINARY_DOUBLE, COMM BINARY_DOUBLE, DEPTNO NUMBER );其中job是职位,mgr是该员工的上司的id,sal是工资,comm是提成,deptno是所属部门。
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
--------------- -------------------- ------------------ --------------- -------------- ----- ----- ---------------
1110 张三 主管 1110 12-3月 -14 5200 0 20
1111 李四 销售 1116 03-11月-15 3400 500 30
1112 王五 销售 1116 25-4月 -12 4400 800 30
1113 赵二 后勤 1110 30-5月 -11 3450 0 40
1114 李磊磊 会计 1110 22-12月-15 2500 0 50
1115 张少丽 销售 1110 11-3月 -16 2400 1400 30
1116 林建国 主管 1116 22-1月 -16 5700 0 20
1117 马富邦 后勤 1116 22-7月 -13 2800 0 40
1118 沈倩 会计 1116 06-5月 -10 2100 0 50
部门表
create table dept( DEPTNO NUMBER, DNAME VARCHAR2(50) );SQL> select * from dept t;
DEPTNO DNAME
-------- --------
20 管理部门
30 销售部门
40 后勤部门
50 金融部门
接下来我们探讨在oracle中如何创建和管理表的技巧
(1)设置适当的默认值
首先我们创建一个测试表:
create table test1 (tid number, tname varchar2(20), hidate date default sysdate);
这里我们创建了三个字段,id、姓名和雇用日期。其中雇佣日期默认是系统当前时间。
我们为词表增加一条数据:
insert into test1(tid,tname) values(1,'jack');
然后取出看一下结果:
select * from test1;
TID TNAME HIDATE
---------- ---------------------------------------- --------------
1 jack 28-8月 -16
可以看到,当我们没有填写日期的时候,我们的雇佣日期刚好是系统的当前时间。
(2)从其他表中获取数据建立新表
我们创建一个新表emp20,其中的数据要求是emp雇员信息表中部门为20的所有雇员的信息:
create table emp20 as select * from emp where deptno=20;
然后我们查看一下,果然就是部门为20的雇员信息:
select * from emp20;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- -------------------- ------------------ ---------- -------------- ----- ----- ----------
1110 张三 主管 1110 12-3月 -14 5200 0 20
1116 林建国 主管 1116 22-1月 -16 5700 0 20
我们只拷贝表结构的时候,在where语句后面加上一个用不成立的条件就可以了(如1=2)。
(3)快速建表
创建一个收入表,其中含有:员工号、姓名、月薪、年薪、部门名称
不难发现,有一些数据我们可以从emp表和deptno里取出,但是有一些
数据(如年薪和部门名称)我们需要间接总结取出,还要给新的字段赋别名:
create table empincome as select empno,ename,sal,sal*12 annlsal,dname from emp e,dept d where e.deptno=d.deptno;
创建完成后,我们查看一下我们创建的新表:
select * from empincome;
EMPNO ENAME SAL ANNLSAL DNAME
---------- -------------------- ----- ------- -----------
1110 张三 5200 62400 管理部门
1111 李四 3400 40800 销售部门
1112 王五 4400 52800 销售部门
1113 赵二 3450 41400 后勤部门
1114 李磊磊 2500 30000 金融部门
1115 张少丽 2400 28800 销售部门
1116 林建国 5700 68400 管理部门
1117 马富邦 2800 33600 后勤部门
1118 沈倩 2100 25200 金融部门
这样我们就快速创建出一个员工的收入表,而且数据我们也都迁移过来了。
注意,之前我们说过一个rownum,是行号:
select rownum,ename from empincome;
ROWNUM ENAME
---------- --------------------
1 张三
2 李四
3 王五
4 赵二
5 李磊磊
6 张少丽
7 林建国
8 马富邦
9 沈倩
其实还有一个rowid,为行地址,可以唯一确定表中某行的位置:
select rowid,ename from empincome;
ROWID ENAME
------------------ --------------------
AAADnQAAEAAAAEcAAA 张三
AAADnQAAEAAAAEcAAB 李四
AAADnQAAEAAAAEcAAC 王五
AAADnQAAEAAAAEcAAD 赵二
AAADnQAAEAAAAEcAAE 李磊磊
AAADnQAAEAAAAEcAAF 张少丽
AAADnQAAEAAAAEcAAG 林建国
AAADnQAAEAAAAEcAAH 马富邦
AAADnQAAEAAAAEcAAI 沈倩
(4)修改表的多种方法
看清楚,是修改表结构,不是修改表中的数据!
修改表有以下方式:
追加新列(add) 修改列(modify) 删除列(drop) 重命名列(rename)
我们首先看一下我们test1表的表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(20)
HIDATE DATE
接下来我们给该表新增一列photo,格式为blob,可存储二进制流的格式:
alter table test1 add photo blob;
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(20)
HIDATE DATE
PHOTO BLOB
如果嫌tname的长度太短,我们可以修改其数据类型,给其增加长度:
alter table test1 modify tname varchar2(40);
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(40)
HIDATE DATE
PHOTO BLOB
我们可以使用drop将刚刚的photo字段删除:
alter table test1 drop column photo;
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
TNAME VARCHAR2(40)
HIDATE DATE
最后,我们修改一下我们的tname,使其更名为username:
alter table test1 rename column tname to username;
看一下表结构:
desc test1
名称 是否为空? 类型
----------------- -------- ------------
TID NUMBER
USERNAME VARCHAR2(40)
HIDATE DATE
(5)删除表
我们先看一下,当前操作员表空间下的所有表:
select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------------------------------------ -------------- ----------
TEST1 TABLE
EMP02 TABLE
TESTSAVEPOINT TABLE
EMP20 TABLE
EMPINCOME TABLE
EMP TABLE
BIN$PIFbfASsQ/azoeQueDQvqw==$0 TABLE
DEPT TABLE
PROCEDURE_TEST TABLE
我们删除EMP02这张表
drop table EMP02;
我们删除的表都可以在oracle的回收站中看到。
①查看回收站
show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
DEPT BIN$PIFbfASsQ/azoeQueDQvqw==$0 TABLE 2016-08-21:11:09:58
EMP02 BIN$FyCatp18TrCgnxnv8Fr07g==$0 TABLE 2016-08-28:10:16:35
可以看到我们刚刚删除的表。
②清空回收站
purge recyclebin
SQL>回收站已清空。
如果我们想彻底删除表,也就是不安放在回收站中,可以使用purge语句:
drop table test1 purge;
执行之后我们去回收站看是没有test1这张表的删除数据的。
(6)给表加约束
我们创建一个测试表,含有id、姓名、性别和薪水。其中性别我们做了约束,只能是
“男”或“女”,添加的薪水必须大于0。
create table test2 (tid number, tname varchar2(20), gender varchar2(4) check (gender in ('男','女')), sal number check (sal >0) );
我们首先添加一条正常的数据:
insert into test2 values(1,'Tom','男',1000);
select * from test2;
TID TNAME GENDER SAL
---------- ---------------------------------------- -------- -----
1 Tom 男 1000
插入成功。
然后我们插入一条数据,让其性别为“哈”:
insert into test2 values(1,'jack','哈',1000);
然后发现报错了:
insert into test2 values(1,'jack','哈',1000)
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (JACK.SYS_C004067)
同样的,我们把薪水设置成小于0的:
insert into test2 values(1,'jack','男',-1000);
也会报错
insert into test2 values(1,'jack','男',-1000)
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (JACK.SYS_C004068)
注意,两次报错的约束条件代号是不一样的(JACK.SYS_C004067和JACK.SYS_C004068)。
上面我们定义的约束仅仅是“检查列值是否满足一个布尔表达式(CHECK)”
数据库通常拥有以下约束:
实体完整性有primary key (主键)
参照完整性有foreign key (外键)
用户自定义完整性有:列表非空(NOT NULL),列表唯一(UNIQUE),
检查列值是否满足一个布尔表达式(CHECK)
前三个的约束我们要通过constraint关键字来实现。
我们创建一个myperson表,使其拥有主键pid,pname不为空,gender只能是“男”和“女”,
email是唯一的,deptno是emp表的外键。
create table myperson( pid varchar2(18) constraint myperson_PK primary key, pname varchar2(4) constraint myperson_Name not null, gender varchar2(4) constraint myperson_Gender check (gender in ('男','女')), email varchar2(30) constraint myperson_Email UNIQUE, deptno number constraint myperson_FK references dept(deptno) ON DELETE CASCADE );
提示:对于ON DELETE CASCADE
这是数据库外键定义的一个可选项,用来设置当主键表中的被参考列的数据发生变化时,
外键表中响应字段的变换规则的。update则是主键表中被参考字段的值更新,delete是指在主键表中删除一条记录。
on update 和 on delete 后面可以跟的词语有四个
no action , set null , set default ,cascade
no action 表示 不做任何操作,
set null 表示在外键表中将相应字段设置为null
set default 表示设置为默认值
cascade 表示级联操作,就是说,如果主键表中被参考字段更新,外键表中也更新,主键表中的记录被删除,外键表中改行也相应删除。
此时我们发现报错
deptno number constraint myperson_FK references dept(deptno) ON DELETE CASCADE
*
第 6 行出现错误:
ORA-02270: 此列列表的唯一或主键不匹配
原因是我们没有给之前的dept表创建主键:
desc dept;
名称 是否为空? 类型
----------------- -------- ------------
DEPTNO NUMBER
DNAME VARCHAR2(50)
外键一定要是另一张表的主键,所以这里我们修改一下dept表,使其deptno为主键:
alter table dept modify deptno number constraint dept_PK primary key;
SQL>表已更改。
然后我们看一下dept表结构:
desc dept;
名称 是否为空? 类型
----------------- -------- ------------
DEPTNO NOT NULL NUMBER
DNAME VARCHAR2(50)
此时deptno已经是表dept的主键了。
我们再次执行上面的建表语句,我们就创建成功了。
注意,我们上面加的“myperson_XXX”,是一个约束的名字,当出现错误的时候,就会报该
约束的名称,这样使用这个表的其它人就明白自己插入的数据哪里不合适了。
例如我们还是将插入的数据的性别设置成“哈”:
insert into myperson values('p001','jack','哈','jack@126.com',20);
发现报错:
insert into myperson values('p001','jack','哈','jack@126.com',20)
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (JACK.MYPERSON_GENDER)
可以看到,我们违反了jack用户表空间下名为myperson_gender的约束(性别约束),一目了然。
转载请注明出处:http://blog.csdn.net/acmman/article/details/52366264
相关文章推荐
- Oracle的学习二:表管理(数据类型、创建/修改表、添加/修改/删除数据、数据查询)
- Oracle的学习二:表管理(数据类型、创建/修改表、添加/修改/删除数据、数据查询)
- Oracle学习----创建和管理表
- Oracle学习(九):创建和管理表
- oracle学习用户创建和权限管理
- 全面学习ORACLE Scheduler特性(4)创建和管理Schedule
- Oracle 11g 学习六:表的创建及管理
- 【Oracle学习】之 数据库对象的创建与管理
- oracle 学习笔记 - 创建和管理表
- 全面学习ORACLE Scheduler特性(4)创建和管理Schedule
- Oracle学习(9):创建和管理表
- oracle 10g 学习之创建和管理表(7)
- 全面学习ORACLE Scheduler特性(4)创建和管理Schedule
- 全面学习ORACLE Scheduler特性(4)创建和管理Schedule
- ORACLE DBA学习笔记--管理归档日志文件
- ORACLE创建用户 管理用户常用语句创建用户的过程
- ORACLE DBA学习笔记--撤消表空间的管理
- Oracle管理与维护.手工创建数据库以及脚本
- Oracle管理与维护.手工创建数据库以及脚本
- Oracle基础学习三:过程PROCEDURE 和函数FUNCTION 的创建及调用