Oracle完全复制表结构的存储过程

处理Oracle分表的问题,需要为程序创建一个自动分表的存储过程,需要保证所有表结构,约束,索引等等一致。
说明:此Oracle为19c版本。

create or replace procedure COPYTABLE									      --存储过程名称
(tableName in varchar2, newTable in varchar2, dateStr in varchar2)			  --相关参数
  authid current_user as							                          --调用者权限
  v_drop_table_sql varchar2(200);                                             --
  v_create_table_sql varchar2(4000);                                          --
  v_add_default_sql varchar2(4000);                                           --
  i_table_count number;                                                       --
  cursor default_cols is                                                      --默认值游标
    select COLUMN_NAME, DATA_DEFAULT                                          --
      from user_tab_columns                                                   --
     where DATA_DEFAULT is not null                                           --
       and TABLE_NAME = tableName;                                            --
  v_add_primary_sql clob;                                                     --
  cursor primary_cols is                                                      --主键游标,虽然主键只能有一个,但为统一起见还是用了游标
    select distinct tmp.TABLE_NAME,                                           --
                    tmp.INDEX_NAME,                                           --
                    listagg(tmp.COLUMN_NAME)                                  --
                            over(partition by tmp.TABLE_NAME)) as pri_cols    --
      from (select i.TABLE_NAME,                                              --
                   i.INDEX_NAME,                                              --
                   i.COLUMN_NAME,                                             --
                   i.COLUMN_POSITION                                          --
              from user_ind_columns i                                         --
              join user_constraints c                                         --
                on i.INDEX_NAME = c.index_name                                --
             where c.CONSTRAINT_TYPE = 'P'                                    --
               and i.TABLE_NAME = tableName                                   --
             order by 1, 2, 4) tmp;                                           --
  v_add_unique_sql clob;                                                      --唯一约束游标
  cursor unique_cons is                                                       --
    select distinct tmp.TABLE_NAME,                                           --
                    tmp.INDEX_NAME,                                           --
                    listagg(tmp.COLUMN_NAME)                                  --
                            over(partition by tmp.TABLE_NAME,                 --
                                 tmp.INDEX_NAME)) as uni_cols,                --
                    replace(listagg(tmp.COLUMN_NAME)                          --
                                    over(partition by tmp.INDEX_NAME)),       --
                            ',',                                              --
                            '_') as new_indexname                             --
      from (select i.TABLE_NAME,                                              --
                   i.INDEX_NAME,                                              --
                   i.COLUMN_NAME,                                             --
                   i.COLUMN_POSITION                                          --
              from user_ind_columns i                                         --
              join user_constraints c                                         --
                on i.INDEX_NAME = c.index_name                                --
             where c.CONSTRAINT_TYPE = 'U'                                    --
               and i.TABLE_NAME = tableName                                   --
             order by 1, 2, 4) tmp;                                           --
  v_create_index_sql clob;                                                    --非唯一非主键索引游标
  cursor normal_indexes is                                                    --
    select distinct tmp.TABLE_NAME,                                           --
                    tmp.INDEX_NAME,                                           --
                    listagg(tmp.COLUMN_NAME)                                  --
                            over(partition by tmp.TABLE_NAME,                 --
                                 tmp.INDEX_NAME)) as index_cols               --
      from (select i.TABLE_NAME,                                              --
                   i.INDEX_NAME,                                              --
                   c.COLUMN_NAME,                                             --
                   c.COLUMN_POSITION                                          --
              from user_indexes i                                             --
              join user_ind_columns c                                         --
                on i.INDEX_NAME = c.INDEX_NAME                                --
             where index_type = 'NORMAL'                                      --
               and i.TABLE_NAME = tableName                                   --
               and i.uniqueness = 'NONUNIQUE'                                 --
             order by 1, 2, 4) tmp;                                           --
  v_create_unique_index_sql clob;                                             --不是由唯一约束生成的唯一索引游标
  cursor unique_cols is                                                       --
    select distinct tmp.TABLE_NAME,                                           --
                    tmp.INDEX_NAME,                                           --
                    listagg(tmp.COLUMN_NAME)                                  --
                            over(partition by tmp.TABLE_NAME,                 --
                                 tmp.INDEX_NAME)) as index_cols               --
      from (select u_i.TABLE_NAME,                                            --
                   u_i.INDEX_NAME,                                            --
                   c.COLUMN_NAME,                                             --
                   c.COLUMN_POSITION                                          --
              from (select *                                                  --
                      from user_indexes                                       --
                     where table_name = tableName                             --
                       and index_type = 'NORMAL'                              --
                       and index_name not in                                  --
                           (select index_name                                 --
                              from user_constraints                           --
                             where table_name = tableName                     --
                               and index_name is not null)) u_i               --
              join user_ind_columns c                                         --
                on u_i.INDEX_NAME = c.INDEX_NAME                              --
             where u_i.TABLE_NAME = tableName                                 --
               and u_i.uniqueness = 'UNIQUE'                                  --
             order by 1, 2, 4) tmp;                                           --
begin                                                                                               --
  execute immediate  'select count(*) from tabs where table_name = '''||newTable||'''' into  i_table_count;                                       --
  if i_table_count > 0 then                                                                         --
      v_drop_table_sql := 'drop table '||newTable||' cascade constraints';                          --
      execute immediate v_drop_table_sql;                                                           --
  end if;                                                                                           --
  v_create_table_sql := 'create table ' || newTable || ' as select * from ' ||                      --创建表结构
                        tableName || ' where 1=2';                                                  --
  execute immediate v_create_table_sql;                                                             --
  for c1 in default_cols loop                                                                       --添加默认值
    v_add_default_sql := 'alter table ' || newTable || ' modify ' ||                                --
                         c1.column_name || ' default ' || c1.DATA_DEFAULT;                          --
    execute immediate v_add_default_sql;                                                            --
  end loop;                                                                                         --
  for c3 in primary_cols loop                                                                       --添加主键约束
    v_add_primary_sql := 'alter table ' || newTable ||                                              --
                         ' add constraint Pk_' || newTable ||                                       --
                         ' primary key(' || c3.pri_cols || ')';                                     --
    execute immediate v_add_primary_sql;                                                            --
  end loop;                                                                                         --
  for c4 in unique_cons loop                                                                        --添加唯一性约束,由于原约束名可能由于创建约束的方法不同,存在系统自定义的名字,因此这里直接命名唯一约束
    v_add_unique_sql := 'alter table ' || newTable || ' add constraint U_' ||                       --
                        c4.new_indexname || ' unique(' || c4.uni_cols || ')';                       --
    execute immediate v_add_unique_sql;                                                             --
  end loop;                                                                                         --
  for c5 in normal_indexes loop                                                                     --创建非主键且非唯一的索引,索引名字直接继承自主表,后缀dateStr以示不同
    v_create_index_sql := 'create index ' || c5.index_name || '_' ||                                --
                          dateStr || ' on ' || newTable || '(' ||                                   --
                          c5.index_cols || ')';                                                     --
    execute immediate v_create_index_sql;                                                           --
  end loop;                                                                                         --
  for c6 in unique_cols loop                                                                        --创建不是由于约束生成的唯一索引
    v_create_unique_index_sql := 'create unique index ' || c6.index_name || '_' ||                  --
                                 dateStr || ' on ' || newTable || '(' ||                            --
                                 c6.index_cols || ')';                                              --
    execute immediate v_create_unique_index_sql;                                                    --
  end loop;                                                                                         --
end COPYTABLE;                                                                                      --
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值