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

[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

时间: 2024-10-19 00:24:57

[20160713]修改表结构增加1列与缺省值.txt的相关文章

必须会的SQL语句(二) 创建表、修改表结构、删除表_MsSql

1.创建数据库表 --使用哪个数据库,如果不写这一句是默认的数据库,也可以用鼠标选当前数据库 use testDB --创建表 Create Table tablename ( --id表示字段名 --int 数据类型 --primary key 主键 --not null 非空 --identity(1,1)初始值是1 每次自增长1 id int primary key not null identity(1,1), --unique 唯一 name varchar(20) not null

mysql 修改表/字段 增加/删除表索引

mysql教程 修改表/字段 增加/删除表索引 create table test (blob_col blob, index(blob_col(10)));在mysql 5.1中,对于myisam和innodb表,前缀可以达到1000字节长.请注意前缀的限制应以字节为单位进行测量,而create table语句中的前缀长度解释为字符数.当为使用多字节字符集的列指定前缀长度时一定要加以考虑. 还可以创建fulltext索引.该索引可以用于全文搜索.只有myisam存储引擎支持fulltext索引

mysql-MySQL5.0,使用触发器修改表结构

问题描述 MySQL5.0,使用触发器修改表结构 需求: 表t_fault_code记录故障信息编码, 表t_fault_record记录故障记录, 表t_fault_count记录每日的故障统计 现在,code表中增加一条记录时,需要在count表中新增一列,用来存储record表中该故障的出现次数.我的思路: 创建3个触发器, trigger 1:code表insert一条记录后,查询count表中是否已经存在该列(列名:t_fault_code.Source).如果不存在,新增一列. tr

MySQL中修改表结构时需要注意的一些地方_Mysql

MySql 在修改表结构的时候可能会中断产品的正常运行影响用户体验,甚至更坏的结果,丢失数据.不是所有的数据库管理员.程序员.系统管理员都非常了解Mysql能避免这种情况.DBA会经常碰到这种生产中断的情况,当升级脚本修改了应用层和数据库层,或者缺乏经验的管理员.开发在不是很了解Mysql内部工作机制的情况下修改了规范文件. 真相是: 直接修改表结构的过程中会锁表(在5.6版本之前) 在线的数据定义语言在5.6版本不总是在线的而且也会锁表 就算使用Percona工具包(在线修改定义文件)也会有若

mysql修改表结构方法实例详解_Mysql

本文实例讲述了mysql修改表结构方法.分享给大家供大家参考.具体如下: mysql修改表结构使用ALTER TABLE语句,下面就为您详细介绍mysql修改表结构的语句写法,希望对您学习mysql修改表结构方面能有所帮助. ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...] alter_specification: ADD [COLUMN] create_definition [FIRST | AFTER column_nam

[20171113]修改表结构删除列相关问题.txt

[20171113]修改表结构删除列相关问题.txt --//维护表结构删除字段一般都是先 ALTER TABLE <table_name> SET UNUSED (<column_name>); --//然后等空闲时候删除列. ALTER TABLE <table_name> DROP UNUSED COLUMNS CHECKPOINT <n>; --//参考文档: https://docs.oracle.com/cd/E11882_01/server.1

看实例学VFP:用sql命令修改表结构

在看实例学VFP:用sql语句修改数据表记录一文中介绍过用sql语句修改表记录的值,实际vfp中也可以用sql语言中的Alter语句动态的修改表结构.虽然可以实现这样的操作,但是我觉得尽可能还是不要在程序中动态修改表结构,因为这样有可能会造成程序的不稳定以及其它的意外情况. vfp中对表结构的操作主要是增加字段.修改字段.重命名字段和删除字段这四项,sql中修改表结构的语句是Alter语句,那么和这四项操作相对应的Alter语句格式可以总结如下: 增加字段:alter talbe 表名 add

SQL Server阻止保存修改表结构的解决方法_MsSql

在我们的程序开发中,有时候会由于需求的变化而要修改数据库中的表结构.可能是增减列,也可能是修改数据类型,或者修改列名等等.但修改表结构是个危险操作,默认情况下,当你修改表结构时,会弹出如下提示框 上图是修改DeUser表中列的数据类型(从varchar修改为int),然后保存时弹出的提示框.如果我们不想重新创建这张表,只是想在原有的基础上修改它的结构该怎么办呢? 步骤如下: 步骤1.打开SQL Server Management Studio 步骤2.选择Tools (工具菜单) 步骤3.选择O

sqlserver 2008手工修改表结构,表不能保存的问题与解决方法_mssql2005

如果点击"保存文本文件"将会弹出保存文本文件的对话框口, 保存的文本文件中的内容是如下: /*    2010年4月5日0:34:53    用户:    服务器: LONGGEL    数据库: longgel    应用程序: */ ChildCaiClass 保存的对于我来说简直是没用的信息,只是记录了事务的发生时间和一些相关信息,结果这样操作了数据库的结构还是没能修改并保存,而是继续弹出上面的那个窗口,这下我就郁闷了. 点击"取消"却弹出 同样也是没有完成表