[20160713]修改表结构增加1列与缺省值.txt

简介: [20160713]修改表结构增加1列与缺省值.txt --昨天看yangtingkun的blog,提到一个非常有趣的测试,链接: --yangtingkun.net/?p=1483,我自己做一些补充测试: 1.

[20160713]修改表结构增加1列与缺省值.txt

--昨天看yangtingkun的blog,提到一个非常有趣的测试,链接:
--yangtingkun.net/?p=1483,我自己做一些补充测试:

1.环境:
SCOTT@book> @ &r/ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

create table t (id number,name varchar2(20));
insert into t values (1,'a');
commit ;

SCOTT@book> select rowid,t.* from t;
ROWID                      ID NAME
------------------ ---------- --------------------
AAAXNfAAEAAAAL7AAA          1 a

SCOTT@book> @ &r/rowid AAAXNfAAEAAAAL7AAA
    OBJECT       FILE      BLOCK        ROW DBA                  TEXT
---------- ---------- ---------- ---------- -------------------- ----------------------------------------
     95071          4        763          0 4,763                alter system dump datafile 4 block 763 ;

2.11g开始有一个新特性,增加一列加缺省值,可以很快完成。测试如下:

SCOTT@book> alter table t add memo1 varchar2(20) default 'test' not null;
Table altered.

SCOTT@book> select rowid,t.* from t;
ROWID                      ID NAME                 MEMO1
------------------ ---------- -------------------- --------------------
AAAXNfAAEAAAAL7AAA          1 a                    test

--实际上memo1='test',并没有保存在对应的数据块中。通过bbed观察:
SCOTT@book> alter system checkpoint ;
System altered.

BBED> set dba 4,763
        DBA             0x010002fb (16777979 4,763)

BBED> x /rncc *kdbr[0]
rowdata[0]                                  @8180
----------
flag@8180: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8181: 0x01
cols@8182:    2

col    0[2] @8183: 1
col    1[1] @8186: a


3.如果这样增加1列如何呢?
SCOTT@book> alter table t add memo2 varchar2(20) default 'test2' ;
Table altered.

SCOTT@book> alter system checkpoint ;
System altered.

SCOTT@book> select rowid,t.* from t;
ROWID                      ID NAME                 MEMO1                MEMO2
------------------ ---------- -------------------- -------------------- --------------------
AAAXNfAAEAAAAL7AAA          1 a                    test                 test2

BBED> x /rncc *kdbr[0]
rowdata[0]                                  @8165
----------
flag@8165: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8166: 0x02
cols@8167:    4

col    0[2] @8168: 1
col    1[1] @8171: a
col    2[0] @8173: *NULL*
col    3[5] @8174: test2

--可以发现相应块的信息已经修改,所以前面第1种修改方式会非常块,第2种要修改数据块。注意1个细节col    2[0] @8173: *NULL*,块中保存信息是NULL。
--而上面查询显示的是MEMO1='test'.如果你使用参数advanced看执行计划:

SCOTT@book> @ &r/dpc '' advanced
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  63713zdrgk2ky, child number 0
-------------------------------------
select rowid,t.* from t
Plan hash value: 1601196873
---------------------------------------------------------------------------
| Id  | Operation         | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |        |       |     3 (100)|          |
|   1 |  TABLE ACCESS FULL| T    |      1 |    61 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / T@SEL$1
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('11.2.0.4')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "T"@"SEL$1")
      END_OUTLINE_DATA
  */
Column Projection Information (identified by operation id):
-----------------------------------------------------------
   1 - ROWID[ROWID,10], "T"."ID"[NUMBER,22], "T"."NAME"[VARCHAR2,20],
       NVL("T"."MEMO1",'test')[20], "T"."MEMO2"[VARCHAR2,20]

--//注意Column Projection Information (identified by operation id):,NVL("T"."MEMO1",'test'),也就是实际"T"."MEMO1"是NULL,显示的是'test'.

4.但是oracle忽略一种情况,如果执行default ''呢?执行如下:
SCOTT@book> alter table t add memo3 varchar2(20) default null not null;
alter table t add memo4 varchar2(20) default null not null
            *
ERROR at line 1:
ORA-01758: table must be empty to add mandatory (NOT NULL) column


SCOTT@book> alter table t add memo3 varchar2(20) default '' not null;
Table altered.

--//default null not null;无法通过,但是oracle忽略的'' 就是NULL。
--//这是一个矛盾的定义,缺省是''实际是NULL与后面的not null冲突。

SCOTT@book> select rowid,t.* from t;
ROWID                      ID NAME                 MEMO1                MEMO2                MEMO3
------------------ ---------- -------------------- -------------------- -------------------- --------------------
AAAXNfAAEAAAAL7AAA          1 a                    test                 test2

SCOTT@book> @ &r/dpc '' advanced

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - ROWID[ROWID,10], "T"."ID"[NUMBER,22], "T"."NAME"[VARCHAR2,20],
       NVL("T"."MEMO1",'test')[20], "T"."MEMO2"[VARCHAR2,20],
       "T"."MEMO3"[VARCHAR2,20]

--//这里的"T"."MEMO3"是直接显示。
SCOTT@book> column BINARYDEFVAL format a30
SCOTT@book> select * from sys.ecol$;
   TABOBJ#     COLNUM BINARYDEFVAL
---------- ---------- ------------------------------
     95071          3 74657374

SCOTT@book> select dump('test',1016) from dual ;
DUMP('TEST',1016)
-----------------------------------------------
Typ=96 Len=4 CharacterSet=ZHS16GBK: 74,65,73,74

--并没有memo3的缺省定义。
--这样就出现了矛盾的输出。

SCOTT@book> set null null
SCOTT@book> select rowid,t.* from t where memo3 is null;
no rows selected

SCOTT@book> select rowid,t.* from t where memo3 is not null;
ROWID                      ID NAME                 MEMO1                MEMO2                MEMO3
------------------ ---------- -------------------- -------------------- -------------------- --------------------
AAAXNfAAEAAAAL7AAA          1 a                    test                 test2                null

目录
相关文章
|
2月前
|
存储 前端开发 Oracle
物化视图添加删除列测试
物化视图添加删除列测试
12 2
|
9月前
|
SQL 关系型数据库 MySQL
[MySQL]数据的增加(插入)、修改、删除与计算列
[MySQL]数据的增加(插入)、修改、删除与计算列
|
关系型数据库 MySQL 索引
mysql新建数据时判断表,字段,索引是否存在
mysql新建数据时判断表,字段,索引是否存在
91 0
测试关于索引的操作- 修改索引
测试关于索引的操作- 修改索引
|
存储 SQL 数据库
DM8数据库批量创建表,插入数据,更改表信息,删除测试
在测试产品的功能和性能的时候需要大量数据表,我们可以通过**游标**和**存储过程**批量创建测试表,插入测试数据,更改测试表,删除测试表。
|
SQL 监控 测试技术
[20171113]修改表结构删除列相关问题4.txt
[20171113]修改表结构删除列相关问题4.txt --//连续写了3篇修改表结构删除列的相关问题,链接如下: http://blog.itpub.net/267265/viewspace-2147158/ http://blog.
967 0
|
Oracle 关系型数据库 数据库管理
[20171113]修改表结构删除列相关问题2.txt
[20171113]修改表结构删除列相关问题2.txt --//测试看看修改表结构删除列产生的redo向量,对这些操作细节不了解,分析redo看看. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING             ...
1029 0
|
Oracle 关系型数据库
[20171113]修改表结构删除列相关问题3.txt
[20171113]修改表结构删除列相关问题3.txt --//维护表结构删除字段一般都是先 ALTER TABLE SET UNUSED (); --//然后等空闲时候删除列.
748 0
|
SQL Oracle 关系型数据库
[20171113]修改表结构删除列相关问题.txt
[20171113]修改表结构删除列相关问题.txt --//维护表结构删除字段一般都是先 ALTER TABLE SET UNUSED (); --//然后等空闲时候删除列.
833 0