oracle 表字段顺序_Oracle表中新加字段时默认的排列顺序可以修改吗?

本帖最后由 macrowho 于 2014-1-22 17:24 编辑

例如表T

create table t

(

id number,

col1 varchar2(10),

col2 varchar2(10),

col3 varchar2(10)

);

SQL> desc t

Name                                      Null?    Type

----------------------------------------- -------- ----------------------------

ID                                                 NUMBER

COL1                                               VARCHAR2(10)

COL2                                               VARCHAR2(10)

COL3                                               VARCHAR2(10)

SQL>

需要加一列

alter table t add col0 varchar2(10);

SQL> desc t

Name                                      Null?    Type

----------------------------------------- -------- ----------------------------

ID                                                 NUMBER

COL1                                               VARCHAR2(10)

COL2                                               VARCHAR2(10)

COL3                                               VARCHAR2(10)

COL0                                               VARCHAR2(10)

我希望新加的COL0排在COL1的前面,不考虑重新建表,做视图,同义词等手段,有什么其他方法吗?

--------------------------------------------------------------------------------

首先感谢 @带来的12C新特性,12C版本以下的童鞋只能观望一下喽  做了个小实验12C中确实可以解决我的需求,同时物理结构不发生改变,在我看到结果的时候也比较困惑oracle是怎么实现的,整理了一下头脑后,发现column_id很可疑,遂又继续验证了一步,嘿嘿 过程很有趣哟~~,下面是实验过程

试图测试性能(起初以为会有物理变化)

SQL> drop table t purge;

Table dropped.

SQL> create table t

2  (

3                   id number,

4                   col1 varchar2(128),

5                   col2 varchar2(128),

6                   col3 varchar2(128)

7  );

Table created.

SQL> insert into t select object_id,object_name,owner,object_type from dba_objects;

19386 rows created.

Elapsed: 00:00:02.56

......

SQL> insert into t select * from t;

620352 rows created.

Elapsed: 00:00:02.40

......

SQL> insert into t select * from t;

9925632 rows created.

Elapsed: 00:01:54.85

SQL> commit;

Commit complete.

Elapsed: 00:00:00.09

SQL> select count(1) from t;

COUNT(1)

----------

19851264

Elapsed: 00:00:42.43

SQL>

查看当前表中列的的顺序

SQL> SELECT column_name, column_id FROM user_tab_cols  WHERE table_name = 'T' order by 2;

COLUMN_NAME           COLUMN_ID

-------------------- ----------

ID                            1

COL1                          2

COL2                          3

COL3                          4

Elapsed: 00:00:00.07

ROWID:AAAE1NAAEAAAACDAAA    4号文件131号块的第一行数据

SQL> SELECT dbms_rowid.rowid_block_number(ROWID) bno, dbms_rowid.rowid_relative_fno(ROWID) fno, ROWID, t.* FROM t where rownum=1;

BNO        FNO ROWID                      ID

---------- ---------- ------------------ ----------

131          4 AAAE1NAAEAAAACDAAA        652

Elapsed: 00:00:00.07

设置列为invisible之前dump出的block结果

SQL> alter system dump datafile 4 block 131;

System altered.

节选前三行:

block_row_dump:

tab 0, row 0, @0xb19

tl: 37 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 57

col  1: [14]  56 24 49 4f 46 55 4e 43 4d 45 54 52 49 43

col  2: [ 6]  50 55 42 4c 49 43

col  3: [ 7]  53 59 4e 4f 4e 59 4d

tab 0, row 1, @0xb3e

tl: 40 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 58

col  1: [23]

56 5f 24 49 4f 46 55 4e 43 4d 45 54 52 49 43 5f 48 49 53 54 4f 52 59

col  2: [ 3]  53 59 53

col  3: [ 4]  56 49 45 57

tab 0, row 2, @0xb66

tl: 45 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 59

col  1: [22]

56 24 49 4f 46 55 4e 43 4d 45 54 52 49 43 5f 48 49 53 54 4f 52 59

col  2: [ 6]  50 55 42 4c 49 43

col  3: [ 7]  53 59 4e 4f 4e 59 4d

修改列为invisible

SQL> ALTER TABLE  t  MODIFY( COL1 INVISIBLE, COL2 INVISIBLE, COL3 INVISIBLE);

Table altered.

Elapsed: 00:00:00.94

此时column_id变成了NULL

SQL> SELECT column_name, column_id FROM user_tab_cols  WHERE table_name = 'T' order by 2;

COLUMN_NAME           COLUMN_ID

-------------------- ----------

ID                            1

COL1

COL3

COL2

Elapsed: 00:00:00.08

SQL> alter system dump datafile 4 block 131;

System altered.

设置invisible之后,查看dump结果:

block_row_dump:

tab 0, row 0, @0xb19

tl: 37 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 57

col  1: [14]  56 24 49 4f 46 55 4e 43 4d 45 54 52 49 43                          --为发生变化

col  2: [ 6]  50 55 42 4c 49 43

col  3: [ 7]  53 59 4e 4f 4e 59 4d

tab 0, row 1, @0xb3e

tl: 40 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 58

col  1: [23]

56 5f 24 49 4f 46 55 4e 43 4d 45 54 52 49 43 5f 48 49 53 54 4f 52 59

col  2: [ 3]  53 59 53

col  3: [ 4]  56 49 45 57

tab 0, row 2, @0xb66

tl: 45 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 59

col  1: [22]

56 24 49 4f 46 55 4e 43 4d 45 54 52 49 43 5f 48 49 53 54 4f 52 59

col  2: [ 6]  50 55 42 4c 49 43

col  3: [ 7]  53 59 4e 4f 4e 59 4d

Elapsed: 00:00:00.03

添加新的列COL0

SQL> ALTER TABLE t  ADD ( COL0 VARCHAR2(10));

Table altered.

Elapsed: 00:00:00.16

新添加的列的id变为了2

SQL> SELECT column_name, column_id FROM user_tab_cols  WHERE table_name = 'T' order by 2;

COLUMN_NAME           COLUMN_ID

-------------------- ----------

ID                            1

COL0                          2

COL1

COL3

COL2

添加col0之后,此块的dump结果:

block_row_dump:

tab 0, row 0, @0xb19

tl: 37 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 57

col  1: [14]  56 24 49 4f 46 55 4e 43 4d 45 54 52 49 43                    --仍然没有变化原因是因为这列上没有值

col  2: [ 6]  50 55 42 4c 49 43

col  3: [ 7]  53 59 4e 4f 4e 59 4d

tab 0, row 1, @0xb3e

tl: 40 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 58

col  1: [23]

56 5f 24 49 4f 46 55 4e 43 4d 45 54 52 49 43 5f 48 49 53 54 4f 52 59

col  2: [ 3]  53 59 53

col  3: [ 4]  56 49 45 57

tab 0, row 2, @0xb66

tl: 45 fb: --H-FL-- lb: 0x1  cc: 4

col  0: [ 3]  c2 16 59

col  1: [22]

56 24 49 4f 46 55 4e 43 4d 45 54 52 49 43 5f 48 49 53 54 4f 52 59

col  2: [ 6]  50 55 42 4c 49 43

col  3: [ 7]  53 59 4e 4f 4e 59 4d

更新此列上的值

SQL> update t set col0='000' where rowid='AAAE1NAAEAAAACDAAA';

1 row updated.

Elapsed: 00:00:00.03

SQL> commit;

Commit complete.

查询结果,COL的值为000

SQL> SELECTt.id,t.col0,t.col1,t.col2,t.col3from t WHERE ROWID = 'AAAE1NAAEAAAACDAAA';

ID COL0       COL1                                     COL2       COL3

---------- ---------- ---------------------------------------- ---------- ----------

652 000SYS_LOB0000000651C00002$$                SYS        LOB

Elapsed: 00:00:00.01

到这里,偶然发现一个可爱的情况,使用select * 时,在结果中看不到被设置为invisible的列,desc同样看不见,但是如果在select columns_list中手动指定出列名仍然可以被查出来,应该是默认不现实invisible的列

SQL> SELECT *  from t WHERE ROWID = 'AAAE1NAAEAAAACDAAA';

ID COL0

---------- ----------

652 000

Elapsed: 00:00:00.00

更新后继续dump:

SQL> alter system dump datafile 4 block 131;

System altered.

dump结果发生了变化:第一行显示有5列,后面的都是4列

block_row_dump:

tab 0, row 0, @0x4b1

tl: 45 fb: --H-FL-- lb: 0x2 cc: 5

col  0: [ 3]  c2 07 35

col  1: [25]

53 59 53 5f 4c 4f 42 30 30 30 30 30 30 30 36 35 31 43 30 30 30 30 32 24 24

col  2: [ 3]  53 59 53

col  3: [ 3]  4c 4f 42

col  4: [ 3]  30 30 30

tab 0, row 1, @0x13d1

tl: 24 fb: --H-FL-- lb: 0x0  cc: 4

col  0: [ 3]  c2 07 38

col  1: [ 6]  4b 4f 54 41 44 24

col  2: [ 3]  53 59 53

col  3: [ 5]  54 41 42 4c 45

tab 0, row 2, @0x13e9

tl: 28 fb: --H-FL-- lb: 0x0 cc: 4

col  0: [ 3]  c2 07 3b

col  1: [10]  53 59 53 5f 43 30 30 38 32 31

col  2: [ 3]  53 59 53

col  3: [ 5]  49 4e 44 45 58

验证数据,观察发现COL 4的值“303030” 是新加进来的,所以尝试转换,结果与我之前更新的000相符

SQL> set serveroutput on

SQL>

SQL> DECLARE

2        str VARCHAR2(100);

3  BEGIN

4        dbms_stats.convert_raw_value('303030', str);

5        dbms_output.put_line(str);

6  END;

7  /

000

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.13

把所有列设置为visible,并查看结果:

SQL> ALTER TABLE  t  MODIFY( COL1 VISIBLE, COL2 VISIBLE, COL3 VISIBLE);

Table altered.

Elapsed: 00:00:00.43

顺序发生了变化

SQL> SELECT column_name, column_id FROM user_tab_cols  WHERE table_name = 'T' order by 2;

COLUMN_NAME           COLUMN_ID

-------------------- ----------

ID                            1

COL0                          2

COL1                          3

COL2                          4

COL3                          5

SQL> desc t

Name                                      Null?    Type

----------------------------------------- -------- ----------------------------

ID                                                 NUMBER

COL0                                               VARCHAR2(10)

COL1                                               VARCHAR2(128)

COL2                                               VARCHAR2(128)

COL3                                               VARCHAR2(128)

Elapsed: 00:00:00.21

查询结果也发生了变化

SQL> SELECT *  from t WHERE ROWID = 'AAAE1NAAEAAAACDAAA';

ID COL0       COL1                                     COL2       COL3

---------- ---------- ---------------------------------------- ---------- ----------

652 000        SYS_LOB0000000651C00002$$                SYS        LOB

Elapsed: 00:00:00.00

把所有列都设为visible之后 dump结果:

SQL> alter system dump datafile 4 block 131;

System altered.

block_row_dump:

tab 0, row 0, @0x4b1

tl: 45 fb: --H-FL-- lb: 0x2  cc: 5

col  0: [ 3]  c2 07 35

col  1: [25]

53 59 53 5f 4c 4f 42 30 30 30 30 30 30 30 36 35 31 43 30 30 30 30 32 24 24   -----结果与之前一致

col  2: [ 3]  53 59 53

col  3: [ 3]  4c 4f 42

col  4: [ 3]  30 30 30

tab 0, row 1, @0x13d1

tl: 24 fb: --H-FL-- lb: 0x0  cc: 4

col  0: [ 3]  c2 07 38

col  1: [ 6]  4b 4f 54 41 44 24

col  2: [ 3]  53 59 53

col  3: [ 5]  54 41 42 4c 45

tab 0, row 2, @0x13e9

tl: 28 fb: --H-FL-- lb: 0x0  cc: 4

col  0: [ 3]  c2 07 3b

col  1: [10]  53 59 53 5f 43 30 30 38 32 31

col  2: [ 3]  53 59 53

col  3: [ 5]  49 4e 44 45 58

在这次实验中证实oracle 12c中通过设置列的invisible属性,可以实现我问题中的要求;同时物理结构未发生改变,从修改的时间和dump出来的结果来看确实未发生改变,我觉得可能是修改字典表中COLUMN_ID来实现此功能的,纯属个人猜测,没办法想到了就继续验证,其实上面的内容中已有证据,无奈当时未想到,此时重新再来验证一次,实验步骤如下:

SQL> drop table t purge;

Table dropped.

SQL> create table t

2  (

3                   id number,

4                   col1 varchar2(128),

5                   col2 varchar2(128),

6                   col3 varchar2(128)

7  );

Table created.

查看原表column_id

SQL> SELECT table_name, column_name, data_type, column_id FROM dba_tab_columns  WHERE table_name = 'T'  ORDER BY column_id;

TABLE_NAME           COLUMN_NAME          DATA_TYPE             COLUMN_ID

-------------------- -------------------- -------------------- ----------

T                    ID                   NUMBER                        1

T                    COL1                 VARCHAR2                      2

T                    COL2                 VARCHAR2                      3

T                    COL3                 VARCHAR2                      4

修改为invisible

SQL> ALTER TABLE  t  MODIFY( COL1 INVISIBLE, COL2 INVISIBLE, COL3 INVISIBLE);

Table altered.

Elapsed: 00:00:00.06

查看修改后的结果

SQL> SELECT table_name, column_name, data_type, column_id FROM dba_tab_columns  WHERE table_name = 'T'  ORDER BY column_id;

TABLE_NAME           COLUMN_NAME          DATA_TYPE             COLUMN_ID

-------------------- -------------------- -------------------- ----------

T                    ID                   NUMBER                        1

T                    COL2                 VARCHAR2

T                    COL3                 VARCHAR2

T                    COL1                 VARCHAR2

添加新列col0

SQL> ALTER TABLE t  ADD ( COL0 VARCHAR2(10));

Table altered.

Elapsed: 00:00:00.03

查看新加列后的结果

SQL> SELECT table_name, column_name, data_type, column_id FROM dba_tab_columns  WHERE table_name = 'T'  ORDER BY column_id;

TABLE_NAME           COLUMN_NAME          DATA_TYPE             COLUMN_ID

-------------------- -------------------- -------------------- ----------

T                    ID                   NUMBER                        1

T                    COL0                 VARCHAR2                      2

T                    COL1                 VARCHAR2

T                    COL3                 VARCHAR2

T                    COL2                 VARCHAR2

将所有列设置为visible

SQL> ALTER TABLE  t  MODIFY( COL1 VISIBLE, COL2 VISIBLE, COL3 VISIBLE);

Table altered.

Elapsed: 00:00:00.08

查看最终结果

SQL> SELECT table_name, column_name, data_type, column_id FROM dba_tab_columns  WHERE table_name = 'T'  ORDER BY column_id;

TABLE_NAME           COLUMN_NAME          DATA_TYPE             COLUMN_ID

-------------------- -------------------- -------------------- ----------

T                    ID                   NUMBER                        1

T                    COL0                 VARCHAR2                      2

T                    COL1                 VARCHAR2                      3

T                    COL2                 VARCHAR2                      4

T                    COL3                 VARCHAR2                      5

实验暂时画上一个句号。我在所有查询dba_tab_columns表的语句都是order by column_id,结果中column_id为null排在了后面,大家都知道 这是oracle对null的处理,所以我大胆的猜测ORACLE也是使用这种方法来处理对列的显示顺序,当我们设置invisible就将column_id设置为NULL,设置为visible时再设置column_id=表中max(column_id)+1。这算是完美解决吗?

.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值