4.8 维护列

在实际的项目开发过程中,需要对建好的表进行修改,如增加或删除列、修改列名等,这样的操作如果通过重新建表显然是不现实的,本节将讲解如何在已经建好的表中完成列维护。我们在4.2节已经建立了一个表EMPLOYEES。因为该表没有数据,我们先向该表中插入数据,如例子4-16所示。

例子4-16 向表employees中插入数据

    SQL> insert into scott.employees
      2  values(1,'Tom','address1','80854340');
    
    已创建 1 行。

再使用例子4-17查询该表中的所有数据。

例子4-17 查询表employees中的所有数据

    SQL> select *
      2  from scott.employees;
    
    ECODE ENAME                     EADDRESS                       EPHONE
    ---------- -------------------------------------------- ----------------------------------------------- -----------
          1 Tom                       address1                       80854340

该表有4列,分别为ECODE、ENAME、EADDRESS和EPHONE,该表中只有一行记录,员工名字是Tom。

1.插入一列

下面我们演示如何插入一列,在表EMPLOYEES中没有员工性别,这显然是不合适的。我们在表中增加一列SEX,如例子4-18所示。

例子4-18 向表employees中增加一列SEX

    SQL>ALTER TABLE scott.employees
      2   add (
      3       sex    char
      4       );
    表已更改。

为了验证是否增加了一列,使用例子4-19继续查询该表中的所有数据。

例子4-19 验证例子4-18是否向表employees中增加了一列

    SQL> col ename for a10
    SQL> col eaddress for a20
    SQL> col sex for a10
    SQL> select *
      2* from scott.employees
    
    ECODE ENAME      EADDRESS             EPHONE          SEX
    ---------- -------------------- ---------------------------------- ------------------------- ----------
         1 Tom      address1             80854340

从输出结果看出,我们已经成功添加了一列,该列名为SEX,但是值为空。

下面我们再增加一列,并且对该列做修改,列名为DEGREE,如例子4-20所示。

例子4-20 向表employees中增加一列

    SQL> ALTER TABLE scott.employees
      2  add (
      3       degree varchar2(10)
      4       );
    
    表已更改。

此时,更新表中的数据使得员工Tom的SEX列和DEGREE列都有数据,如例子4-21所示。

例子4-21 更新员工Tom的SEX列和DEGREE列的值

    SQL> update scott.employees
      2    set sex ='m',degree='Bachelor'
      3  where ename = 'Tom';
    
    已更新 1 行。

查询该结果,如例子4-22所示。

例子4-22 查询例子4-21的修改结果

    SQL> col sex for a3
    SQL> col eaddress for a10
    SQL> select *
      2* from scott.employees
    
    ECODE ENAME      EADDRESS   EPHONE              SEX    DEGREE
    ---------- -------------------- ----------------- --------------------------- ------ --------------
         1 Tom           address1      80854340        m   Bachelor

输出显示我们成功在新添加的列中增加了数据。但是如果需要修改一个列的约束,比如不允许该列为空(NULL),则需要修改列。

2.修改列

把列DEGREE设置为不允许为空(NULL),如例子4-23所示。

例子4-23 将表employees中的列DEGREE设置为不允许为空

    SQL> ALTER TABLE scott.employees
      2  modify(
      3  degree varchar2(10) not null
      4        )
      5  ;
    
    表已更改。
    SQL> desc scott.employees;
     名称                                      是否为空? 类型
     ----------------------------------------- -------- ---------------
     ECODE                                              NUMBER(4)
     ENAME                                              VARCHAR2(25)
     EADDRESS                                           VARCHAR2(30)
     EPHONE                                             VARCHAR2(15)
     SEX                                                CHAR(1)
     DEGREE                                    NOT NULL VARCHAR2(10)

我们成功修改了列DEGREE的约束,不允许该列为空,用户再次插入数据时,如果该列为空则无法成功插入。

3.删除列

用户既然可以修改表中的列和添加列。自然也可以删除不需要的列。删除列的语法格式为:

    ALTER TABLE tablename DROP COLUMN columnname CASCATE CONTRAINTS

参数CASCADE CONSTRAINTS不是必需的,但是如果该列是一个表的外键,也就是说该表是一个外键引用的父表,而该外健就是此时要删除的列,则需要使用CASCADE CONSTRAINTS参数。

该操作对于Oracle8i以上的版本都适用,但是使用该指令时,数据库系统会重新将表写入磁盘,目的是为了还原需要,这样对于一个大表就会占用较大的还原空间,一旦删除该列将导致无法恢复。

例子4-24 删除表EMPLOYEES中的列DEGREE

    SQL> ALTER TABLE scott.employees DROP COLUMN degree;
    
    表已更改。
    SQL> desc scott.employees;
     名称                                      是否为空? 类型
     ----------------------------------------- -------- -------------
     ECODE                                              NUMBER(4)
     ENAME                                              VARCHAR2(25)
     EADDRESS                                           VARCHAR2(30)
     EPHONE                                             VARCHAR2(15)
     SEX                                                CHAR(1)

上例输出说明,已成功删除表EMPLOYEES中的列DEGREE。

在大表中删除一行非常耗费时间,此时可以在ALTER TABLE语句中使用SET UNUSED子句,这样就将表中某列置成无用的列。其语法如下:

    ALTER TABLE <username.>tablename
    SET UNUSED COLUMN columnname CASCADE CONSTRAINTS;

其实,此时并没有删除该表中该列的数据,而是使得用户查询时看不到该列内容,该列被数据库认为是删除的列。并且一旦该列设置为UNUSED则无法恢复。但数据库空闲时,可以使用如下命令再删除置为无用的列。

    ALTER TABLE <username.>tablename
    DROP UNUSED COLUMNS ;

下面演示如何将一列设置成无用的列。如例子4-25所示,将EPHONE列设置为无用的列。

例子4-25 将表employees中的EPHONE列设置为无用的列

    SQL> ALTER TABLE scott.employees
      2* SET UNUSED  COLUMN ephone
    
    表已更改。
    SQL> select *
      2  from scott.employees;
    
    ECODE ENAME      EADDRESS   SEX
    ---------- ------------------- ------------------- ---
         1 Tom           address1      m

表EMPLOYEES中的列EPHONE设置为无用,此时数据库认为该列已经删除,在使用SQL语句查询时会发现没有列EPHONE的值。

下面删除掉设置为UNUSED的列。

例子4-26 删除掉表employees中设置为UNUSED的列

    SQL> alter table scott.employees
      2  drop unused columns;
    
    表已更改。

4.更改列名字

列名是程序员设计的用来表示一个字段的信息,如果在开发过程中由于某种原因需要对列名进行规范,则需要对已经创建好的表的列名进行修改。修改列名的语句很简单,如下所示。

    ALTER TABLE <username.>employees
    RENAME COLUMN old_columnname
    TO new_columnname;

例子4-27给出修改列名的实例演示,该实例将表EMPLOYEES中的列SEX 改为E_SEX。

例子4-27 将表EMPLOYEES中的列SEX 改为E_SEX

    SQL> alter table scott.emp
      2  rename column sal
      3  to salary;
    
    表已更改。

查询更改结果,如下所示。

    SQL> desc scott.emp;
    名称                                      是否为空? 类型
    ----------------------------------------- -------- ------------------------
    EMPNO                                     NOT NULL NUMBER(4)
    ENAME                                              VARCHAR2(10)
    JOB                                                VARCHAR2(9)
    MGR                                                NUMBER(4)
    HIREDATE                                           DATE
    SALARY                                             NUMBER(7,2)
    COMM                                               NUMBER(7,2)
    DEPTNO                                             NUMBER(2)

从上述输出中可以看到原表中的SAL列名已经改为SALARY了。