您的位置:首页 > 数据库 > Oracle

【oracle学习】5.创建和管理表

2016-08-30 09:06 483 查看
还是先介绍一下我们要用到的两张表以及数据:

员工信息表
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: