【Oracle】数据库用户表结构升级

温馨提示

没完全试验,谨慎参考

场景:

Oracle数据库两个,分别与A用户与B用户,用户名一样,表一样,但由于A在一直开发,根据情况不断添加字段,一开始两库是保持一致的,但一段时间后,B的字段相比A缺失很多,这时候如何进行快速升级B的表结构保持与A同步。

解决思路:

当然最简单的是删用户重导,但对于数据量太大,而且里面数据不是必要的这种虽然简洁,但耗时较长,且没必要,那么是否可以考虑单表扩容,查到单个表的建表语句,将每个字段,alter table xxx add xxx xxx; 这样其实是可行的,但表太多呢。
那么就用到了系统用户视图 user_tab_columns
这时候就要根据字段类型调整alter语句
关于oralce字段,参考:
ORACLE数据库字段类型说明

1.查看我本地数据库发现有以下类型

select distinct data_type from user_tab_columns;

在这里插入图片描述
但比较我们的建表语句
c_length NUMBER(8,2),
qrcode VARCHAR2(128),
status INTEGER,
task_id NUMBER(20),
sys_version VARCHAR2(32),
time_stamp DATE,
发现两者有些不是完全对应的,而且还有default,default这里先不处理了,后续在补充。

先抛出我用到的这几种类型的补充

2.查找字段及添加语句

1.TIMESTAMP(8),TIMESTAMP(7),TIMESTAMP(6),FLOAT,CLOB,DATE
这六种类型相对简单
select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || ';',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('TIMESTAMP(8)',
                     'TIMESTAMP(7)',
                     'TIMESTAMP(6)',
                     'FLOAT',
                     'DATE',
                     'CLOB')
--and table_name not like 'SYS%'
;

由于本地环境TIMESTAMP(8)有default sysdate,改下就是

select 'alter table  ' || table_name || ' add ' || column_name || ' ' ||
       data_type || ' default sysdate;',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('TIMESTAMP(8)',
                     'TIMESTAMP(7)',
                     'TIMESTAMP(6)')
--and table_name not like 'SYS%'
;
2.NUMBER

这个其实是包含INTEGER,NUMBER,而number里又包含NUMBER(x)和NUMBER(x,x)两种情况,所以是三种情形,对应的user_tab_columns里的data_type都是NUMBER,但在补充字段时需要根据情况进行区别
根据data_precision和data_scale进行区分,data_precision是空的那么数据类型就是INTEGER;data_precision有值,但data_scale是0那么就是NUMBER(x),data_scale不为0就是NUMBER(x,x);
ok,sql:

INTEGER
 select 'alter table ' || table_name || ' add ' || column_name ||
       ' INTEGER;',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('NUMBER')
   and data_precision is null;

NUMBER(x)
 select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
        data_type || '(' || data_precision || ')' || ';',
        a.table_name,
        a.column_name,
        a.data_type,
        a.data_length,
        a.data_precision,
        a.data_scale
   from user_tab_columns a
  where data_type in ('NUMBER')
    and data_precision > 1
    and (data_scale = 0 or data_scale is null);

NUMBER(x,x)
select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || '(' || data_precision || ',' || data_scale || ')' || ';',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('NUMBER')
   and data_precision > 1
   and data_scale > 0;

3.VARCHAR2
select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || '(' || data_length || ')' || ';',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('VARCHAR2');

NVARCHAR2,CHAR
这俩不多,懒得写了,后续再调整

3.聚合一下,然后执行

将语句复制到文件里,plsql命令窗口执行即可,或者直接复制到命令窗口执行,提示重复的就不用管了,就是原来已然存在的,不重复的就是新添加进去的。

select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || ';',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale

  from user_tab_columns a
 where data_type in ('FLOAT',
                     'DATE',
                     'CLOB')
union
select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || ' default sysdate;',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('TIMESTAMP(8)', 'TIMESTAMP(7)', 'TIMESTAMP(6)')
--and table_name not like 'SYS%'
union
select 'alter table ' || table_name || ' add ' || column_name ||
       ' INTEGER;',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('NUMBER')
   and data_precision is null
union

select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || '(' || data_precision || ')' || ';',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('NUMBER')
   and data_precision > 1
   and (data_scale = 0 or data_scale is null)
union
select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || '(' || data_precision || ',' || data_scale || ')' || ';',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('NUMBER')
   and data_precision > 1
   and data_scale > 0
union
select 'alter table ' || table_name || ' add ' || column_name || ' ' ||
       data_type || '(' || data_length || ')' || ';',
       a.table_name,
       a.column_name,
       a.data_type,
       a.data_length,
       a.data_precision,
       a.data_scale
  from user_tab_columns a
 where data_type in ('VARCHAR2');

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

实施工程师木易

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值