[20141116]12c下增加字段与缺省值.txt

简介: [20141116]12c下增加字段与缺省值.txt --前一段时间写了一篇表增加字段与缺省值的blog. --链接如下: http://blog.itpub.net/267265/viewspace-1257035/ --12G 增加字段带缺省值,可以很快完成,不需要update表.实际上是增加一个隐含字段,通过位与的方式确定取值方式。

[20141116]12c下增加字段与缺省值.txt

--前一段时间写了一篇表增加字段与缺省值的blog.
--链接如下:
http://blog.itpub.net/267265/viewspace-1257035/

--12G 增加字段带缺省值,可以很快完成,不需要update表.实际上是增加一个隐含字段,通过位与的方式确定取值方式。

当时的总结如下:
--增加字段带缺省值,在12c下很快完成,不需修改表,但是以后的插入要多付出2个字节的代价(不会增加9个字段带缺省值的吧^_^)
--它通过增加1个隐含字段里面的bit来表示这些字段从那里来读取.
--后续的插入即使insert不带这些字段,其缺省值也插入数据块中.

--如果以后修改了字段的缺省值,会出现什么情况呢?再做一个测试。

1.建立测试环境:
SCOTT@test01p> @ver

BANNER                                                                               CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

create table t (id number);
insert into t values (1);
commit ;
alter table t add (name  varchar2(10) default 'test');


2.测试1:
SCOTT@test01p> select t.* , SYS_NC00002$ from t;
        ID NAME                 SYS_NC0000
---------- -------------------- ----------
         1 test

SCOTT@test01p> @dpc ''  projection
PLAN_TABLE_OUTPUT
--------------------------------------
SQL_ID  9gw3r0y39kyvp, child number 0
-------------------------------------
select t.* , SYS_NC00002$ from t

Plan hash value: 1601196873

--------------------------------------------------------
| Id  | Operation         | Name | E-Rows | Cost (%CPU)|
--------------------------------------------------------
|   0 | SELECT STATEMENT  |      |        |     3 (100)|
|   1 |  TABLE ACCESS FULL| T    |      1 |     3   (0)|
--------------------------------------------------------

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

   1 - "T"."ID"[NUMBER,22], "SYS_NC00002$"[RAW,126],
       DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00002$",0)),NULL,NVL("T"."NAME",'test'),'0',NVL("T"."NAME",'test'),'1',"T"."NAME")[10]

--第2字段的取值实际上执行的是DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00002$",0)),NULL,NVL("T"."NAME",'test'),'0',NVL("T"."NAME",'test'),'1',"T"."NAME")[10]。

select obj#,col#,segcol#,name,default$,type# from sys.col$  where
obj# in ( select object_id from dba_objects where owner=user and object_name='T')
order by col#;

      OBJ#       COL#    SEGCOL# NAME                 DEFAULT$                            TYPE#
---------- ---------- ---------- -------------------- ------------------------------ ----------
     96948          0          2 SYS_NC00002$                                                23
     96948          1          1 ID                                                           2
     96948          2          3 NAME                 'test'                                  1

--上次的blog已经提到增加隐含字段SYS_NC00002$,类型raw。SYS_NC00002$为NULL时,取值来之:

SCOTT@test01p> select * from sys.ecol$ where tabobj#= 96948 and colnum = 3;
   TABOBJ#     COLNUM BINARYDEFVAL           GUARD_ID
---------- ---------- -------------------- ----------
     96948          3 74657374                      0

SCOTT@test01p> host cat d:\tools\sql\conv_c.sql
select utl_raw.cast_to_varchar2(lower('&1')) c60 from dual;

SCOTT@test01p> @conv_c 74657374
C60
------------------------------------
test

3.测试2:
--增加记录看看。
insert into t values(2,'aaaa');
commit;

SCOTT@test01p> select t.* , SYS_NC00002$ from t;
        ID NAME                 SYS_NC0000
---------- -------------------- ----------
         1 test
         2 aaaa                 01

--SYS_NC00002$='01',表示从块中取值。
--如果这时修改name的缺省值,会出现什么情况呢?
--alter table t modify name varchar2(10) default 'lfree';

SCOTT@test01p> alter table t modify name default 'lfree';
Table altered.

SCOTT@test01p> select t.* , SYS_NC00002$ from t;
        ID NAME                 SYS_NC0000
---------- -------------------- ----------
         1 test
         2 aaaa                 01

--ID=1的name依旧是'test',而不是'lfree'.

select obj#,col#,segcol#,name,default$,type# from sys.col$  where
obj# in ( select object_id from dba_objects where owner=user and object_name='TX')
order by col#;

      OBJ#       COL#    SEGCOL# NAME                 DEFAULT$                            TYPE#
---------- ---------- ---------- -------------------- ------------------------------ ----------
     96948          0          2 SYS_NC00002$                                                23
     96948          1          1 ID                                                           2
     96948          2          3 NAME                 'lfree'                                 1

SCOTT@test01p> select * from sys.ecol$ where tabobj#= 96948 ;
   TABOBJ#     COLNUM BINARYDEFVAL           GUARD_ID
---------- ---------- -------------------- ----------
     96948          3 74657374                      0

--也就是讲这两个值是分开存放的。

SCOTT@test01p> insert into t(id) values(3);
1 row created.

SCOTT@test01p> commit ;
Commit complete.

SCOTT@test01p> select t.* , SYS_NC00002$ from t;
        ID NAME                 SYS_NC0000
---------- -------------------- ----------
         1 test
         2 aaaa                 01
         3 lfree                01

4.增加超过9个字段会出现什么情况呢?

--前面的blog我提到增加字段带缺省值,在11G下很快完成,不需修改表,但是以后的插入要多付出2个字节的代价(不会增加9个字段带缺省
--值的吧^_^)
--正常不会增加9个以上的字段,好像很少有这种情况出现把,如果真出现会是什么情况呢?继续测试:

alter table t add (name1  varchar2(10) default 'test1');
alter table t add (name2  varchar2(10) default 'test2');
alter table t add (name3  varchar2(10) default 'test3');
alter table t add (name4  varchar2(10) default 'test4');
alter table t add (name5  varchar2(10) default 'test5');
alter table t add (name6  varchar2(10) default 'test6');
alter table t add (name7  varchar2(10) default 'test7');
alter table t add (name8  varchar2(10) default 'test8');

insert into t(id) values(4);
ommit ;

SCOTT@test01p> select t.* , SYS_NC00002$ from t;
        ID NAME                 NAME1      NAME2      NAME3      NAME4      NAME5      NAME6      NAME7      NAME8      SYS_NC0000
---------- -------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
         1 test                 test1      test2      test3      test4      test5      test6      test7      test8
         2 aaaa                 test1      test2      test3      test4      test5      test6      test7      test8      01
         3 lfree                test1      test2      test3      test4      test5      test6      test7      test8      01
         4 lfree                test1      test2      test3      test4      test5      test6      test7      test8      FF01

--实际上就是隐含列的长度增加1位吧了。

5.分区交换的问题:
另外要注意的一个问题,就是这种表做分区交换的时候会出现问题,因为它存在一个隐含字段,具体看下一篇blog.

目录
相关文章
|
SQL 监控 测试技术
[20171113]修改表结构删除列相关问题4.txt
[20171113]修改表结构删除列相关问题4.txt --//连续写了3篇修改表结构删除列的相关问题,链接如下: http://blog.itpub.net/267265/viewspace-2147158/ http://blog.
965 0
|
Oracle 关系型数据库
[20171113]修改表结构删除列相关问题3.txt
[20171113]修改表结构删除列相关问题3.txt --//维护表结构删除字段一般都是先 ALTER TABLE SET UNUSED (); --//然后等空闲时候删除列.
748 0
|
Oracle 关系型数据库 数据库管理
[20171113]修改表结构删除列相关问题2.txt
[20171113]修改表结构删除列相关问题2.txt --//测试看看修改表结构删除列产生的redo向量,对这些操作细节不了解,分析redo看看. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING             ...
1028 0
|
SQL Oracle 关系型数据库
[20171113]修改表结构删除列相关问题.txt
[20171113]修改表结构删除列相关问题.txt --//维护表结构删除字段一般都是先 ALTER TABLE SET UNUSED (); --//然后等空闲时候删除列.
833 0
|
SQL Shell 测试技术
[20161023]为什么以前可以这样的表.txt
[20161023]为什么以前可以这样的表.txt --上午看https://oracleblog.org/working-case/ora-01401-impdp-same-character/ CREATE TABLE ASS_ACC...
774 0
|
Oracle 关系型数据库 OLAP
[20160910]快速修改表的schema.txt
[20160910]快速修改表的schema.txt --以前也做过例子: http://blog.itpub.net/267265/viewspace-741154/ http://blog.itpub.net/267265/viewspace-744787/ --第1种就是修改数据字典的情况,但是这种存在一定的风险,我当时的测试版本11.2.0.1还有修改obj$的字段spare3. --第2种就是利用交换分区的方法。
828 0
|
Oracle 关系型数据库
[20151024]关于ctas与建立主键.txt
[20151024]关于ctas与建立主键.txt --前一阵子别人问的问题,就是ctas是否可以建立主键,对于这种情况平时不这么建立,我给看看文档。 --平时我建立测试表 create table t as select rownum id ,'test' n...
894 0
|
索引
[20150321]索引空块的问题.txt
[20150321]索引空块的问题.txt --晚上看了: 索引空块较多造成index range scan的IO成本较高 http://www.dbaxiaoyu.
736 0
|
Oracle 关系型数据库 测试技术
[20150314]256列.txt
[20150314]256列.txt --oracle 当1个表超过256列时,要分成几个行片(row pieces),昨天看链接: https://jonathanlewis.
816 0
[20150115]insert多个表.txt
[20150115]insert多个表.txt --别人给我提出一个问题,要把表拆开2个表,能否快速完成这个工作。还是通过例子来说明: SCOTT@test> @ver1 PORT_STRING                    VERSION  ...
680 0