最近在处理一个分表的问题时,需要为程序创建一个自动分表的存储过程,需要保证所有表结构,约束,索引等等一致,此外视图,存储过程,权限等等问题暂不用考虑。

在Mysql中,创建分表的存储过程,相当简单:create table if not exists <new_table_name> like <old_table_name>;即可,约束,索引一应俱全。

但是在Oracle中貌似没有,所以只能自己写,需要考虑的情况比较多,脚本如下:

CREATE OR REPLACE PROCEDURE CREATETABLE(tableName in varchar2,
dateStr in varchar2)
AUTHID CURRENT_USER as
newTable varchar2(32) := tableName || '_' || dateStr; v_create_table_sql clob;
--c1,默认值游标
v_add_default_sql clob;
cursor default_cols is
select COLUMN_NAME, DATA_DEFAULT
from user_tab_columns
where DATA_DEFAULT is not null
and TABLE_NAME = tableName;
--c2 主键的not null不会继承,但not null约束的会继承,因此c2全部注释
/*v_add_notnull_sql clob;
cursor notnull_cols is select COLUMN_NAME from user_tab_columns t where t.NULLABLE='N' and and t.TABLE_NAME=tableName;*/
--c3,主键游标,虽然主键只能有一个,但为统一起见还是用了游标
v_add_primary_sql clob;
cursor primary_cols is
select distinct tmp.TABLE_NAME,
tmp.INDEX_NAME,
to_char(wm_concat(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;
--c4,唯一约束游标
v_add_unique_sql clob;
cursor unique_cons is
select distinct tmp.TABLE_NAME,
tmp.INDEX_NAME,
to_char(wm_concat(tmp.COLUMN_NAME)
over(partition by tmp.TABLE_NAME,
tmp.INDEX_NAME)) as uni_cols,
replace(to_char(wm_concat(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;
--c5,非唯一非主键索引游标
v_create_index_sql clob;
cursor normal_indexes is
select distinct tmp.TABLE_NAME,
tmp.INDEX_NAME,
to_char(wm_concat(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;
--c6,不是由唯一约束生成的唯一索引游标
v_create_unique_index_sql clob;
cursor unique_cols is
select distinct tmp.TABLE_NAME,
tmp.INDEX_NAME,
to_char(wm_concat(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
--创建表结构
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 c2 in notnull_cols loop
v_add_notnull_sql:='alter table '||newTable||' modify '||c2.column_name||' not null';
execute immediate v_add_notnull_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;
--创建非主键且非唯一的索引,索引名字直接继承自主表,后缀dateStr以示不同
for c5 in normal_indexes loop
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 createTable; /

  

Oracle完全复制表结构的存储过程的更多相关文章

  1. oracle 快速复制表结构、表数据

      1.情景展示 根据现有的表,建一个新的表,要求:新表的结构与原有表的表结构一模一样,如何快速实现? 根据现有的表,建一个新的表,要求:新表的结构.数据与原表一模一样,如何实现快速复制旧表? 2.解 ...

  2. 【Oracle】复制表结构和表数据

    1.既复制表结构也复制表数据:CREATE TABLE tab_new AS SELECT * FROM tab_old; 2.只复制表结构:CREATE TABLE tab_new AS SELEC ...

  3. mysql复制表结构及检查表、存储过程是否存在

    mysql命令行复制表结构的方法: 1.只复制表结构到新表 CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2  或者 CREATE TABLE 新表 LIKE 旧表 ...

  4. oracle、mysql、sybase和sqlserver复制表结构和数据

    Sql Server(sybase): 1.复制表结构: 新建表student2,并且结构同表syn_xj_student一致.Sql语句如下: 2.复制表数据,并排除俩表中相同的数据: insert ...

  5. oracle复制表数据,复制表结构

    1.不同用户之间的表数据复制 2.同用户表之间的数据复制 3.B.x中个别字段转移到B.y的相同字段 4.只复制表结构 加入了一个永远不可能成立的条件1=2,则此时表示的是只复制表结构,但是不复制表内 ...

  6. 【Oracle】【2】复制表结构及其数据

    --复制表结构及其数据 create table table_name_new as select * from table_name_old; --只复制表结构 ; --create table t ...

  7. oracle 复制表结构表数据

    create table Uc_t_Department3 as (select * from Uc_t_Department where 1=2);insert into Uc_t_Departme ...

  8. Oracle跨库复制表结构

    1.首先建立远程连接 create public database link LINK_SJPSconnect to system identified by manager using '(DESC ...

  9. oracle 复制表数据,复制表结构

    1.不同用户之间的表数据复制 对于在一个数据库上的两个用户A和B,假如需要把A下表old的数据复制到B下的new,请使用权限足够的用户登入sqlplus:insert into B.new(selec ...

随机推荐

  1. shiro 返回json字符串 + 自定义filter

    前言: 在前后端分离的项目中, 在使用shiro的时候, 我们绝大部分时候, 并不想让浏览器跳转到那个页面去, 而是告诉前端, 你没有登录, 或者没有访问权限. 那这时候, 我们就需要返回json字符 ...

  2. 【杂谈】没有公网IP的电脑如何与外部通信

    前言 前几天突然想到的问题,自己先猜测推理了一番,最后在谢希仁版<计算机网络>找到了权威的解答.这里记录一下自己的思考过程. 网站是如何找到我们的? 我们知道,互联网中的两台电脑要进行通信 ...

  3. Java设计模式学习记录-备忘录模式

    前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...

  4. Linux录制、回放和共享终端操作

    另一篇终端会话共享的文章:Linux终端会话实时共享(kibitz) 使用script命令录制,使用scriptreplay播放录制的操作.共享终端的操作,则需要使用命名管道来实现. 1.1 录制 [ ...

  5. 在go modules中使用replace替换无法直接获取的package(golang.org/x/...)

    上一篇里我们介绍了使用go get进行包管理. 不过因为某些未知原因,并不是所有的包都能直接用go get获取到,这时我们就需要使用go modules的replace功能了.(当然大部分问题挂个梯子 ...

  6. [leetcode]1007. 行相等的最少多米诺旋转

    在一排多米诺骨牌中,A[i] 和 B[i] 分别代表第 i 个多米诺骨牌的上半部分和下半部分.(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字.) 我们可以旋 ...

  7. nginx配置虚拟机

    在/usr/local/nginx/conf目录下nginx.conf文件是nginx的配置文件. 一.通过端口号区分虚拟机 在nginx.conf文件中添加一个Service节点,修改端口号: se ...

  8. JavaScript初学者必看“箭头函数”

    译者按: 箭头函数看上去只是语法的变动,其实也影响了this的作用域. 原文: JavaScript: Arrow Functions for Beginners 译者: Fundebug 为了保证可 ...

  9. 课程作业——Python基础之使用turtle库画出红旗

    代码如下: import turtle # 设置画笔和背景颜色 turtle.color('yellow') turtle.bgcolor('red') # 通过偏移量和尺寸大小画星星 def dra ...

  10. Grunt 入门操作指南

    0.简介 grunt是一个任务自动运行器.简单来讲,用了以后,再也不用每次修改sass后,去生成下css,也再也不用去一遍遍压缩js了 ,也再也不用修改了点点东西就要去刷新页面,也不需要去复杂地建立一 ...