某些系统需要按月分表来保存数据。下面的存储过程演示了如何使用基表来建立每个月的月表。
处理思路是:
    1:首先,为基表建立好表和对应的索引。
    2:将基表保存到一个存储过程需要的表中。
    3:存储过程读取配置表,根据配置表中的名字,去数据库中查询对应的表的建表语句,然后,用月表的表名去替换语句中的表名,接着就建表。再去查询基表的表是不是有索引,如果有,则从数据库中得到索引的建表语句,然后,替换建表语句中的索引名称和表名称,最后执行建立索引的语句。
 
-- oracle环境的sql
-- 基础表准备
drop table base_config_monthly_table;
create table base_config_monthly_table
(
base_table_name varchar2(50),
valid_flag number(1) default 1,
remark varchar2(1000)
); select * from base_config_monthly_table ;
insert into base_config_monthly_table(base_table_name,valid_flag,remark)
select 'aa_wanglc_test',1,'王路长提供的样例' from dual;
commit; -- 待用函数的测试
SELECT REPLACE( '', substr('',4,4), '****') from dual;
select instr('abcdef','d') from dual;
select length('abdf') from dual;
select to_char(add_months(trunc(sysdate),-1),'yyyy') from dual;
select to_char(1,'fm00') from dual; CREATE TABLE aa_wanglc_test AS SELECT * FROM dual;
SELECT * FROM aa_wanglc_test;
CREATE INDEX idx_wt_d009091 ON aa_wanglc_test(dummy); -- 通过基表建立月表,且通过基表的索引建立月表的索引
CREATE OR REPLACE procedure proc_create_monthly_tables
AUTHID CURRENT_USER IS
v_base_monthly_table base_config_monthly_table%rowtype; -- 配置表
v_base_ddl varchar2(4000); -- 保存基表的sql
v_sql varchar2(4000); -- 最终需要使用的sql
v_new_tableName varchar2(50); -- 月表的表名
v_yyyy varchar2(10); --月表的年变量
v_month number := 0; --月表的月变量
v_current_month varchar2(10); -- 月份的循环变量
v_exists_flag number := 0;
v_base_table_name_upper varchar2(50); -- 大写格式的基表名字 cursor v_cur_get_basetable is
select * from base_config_monthly_table where valid_flag = 1; type cur_get_index is ref cursor; --声明一个动态游标类型,因为游标不是类型所以要声明一个动态游标类型,需要查询每个基表的索引
v_cur_get_index cur_get_index; --声明一个动态游标变量 v_index_ddl varchar2(4000); -- 建立索引的sql
v_index_name_str varchar2(30);
v_index_name_num NUMBER;
v_index_name varchar2(30);
v_old_index_name varchar2(30); begin
open v_cur_get_basetable;
loop
fetch v_cur_get_basetable
into v_base_monthly_table;
exit when v_cur_get_basetable%notfound; select to_char(sysdate,'yyyy') into v_yyyy from dual; select upper(v_base_monthly_table.base_table_name) into v_base_table_name_upper from dual;
--dbms_output.put_line(v_base_table_name_upper);
v_exists_flag := 0;
select count(*) into v_exists_flag from user_tables where table_name = v_base_table_name_upper ; -- 如果基表不存在,则不处理这条配置记录
if v_exists_flag = 0 then
continue;
end if; -- 在数据库系统取得基表的建表语句
SELECT DBMS_METADATA.GET_DDL('TABLE', v_base_table_name_upper)
into v_base_ddl
from dual; --dbms_output.put_line(v_base_ddl);
v_month := 0; loop
v_month := v_month +1;
exit when v_month > 12;
select to_char(v_month,'fm00') into v_current_month from dual;
v_new_tableName := v_base_table_name_upper||'_'||v_yyyy||v_current_month;
-- dbms_output.put_line(v_new_tableName); v_exists_flag := 0;
select count(*) into v_exists_flag from user_tables where table_name = upper(v_new_tableName)
or table_name = '"'||v_new_tableName||'"'; -- dbms_output.put_line(v_exists_flag);
-- 如果月表已经创建,则不再创建
if v_exists_flag > 0 then
continue;
end if; -- 用月表的表名来替换建表语句中的基表表名
SELECT REPLACE(v_base_ddl,
v_base_table_name_upper,
v_new_tableName)
into v_sql
from dual; --dbms_output.put_line(v_sql);
execute IMMEDIATE v_sql; -- 查找索引
v_sql := 'SELECT DBMS_METADATA.GET_DDL('''||CHR(73)||'NDEX'', index_name),index_name
FROM USER_INDEXES WHERE table_name = '''||v_base_table_name_upper||'''
AND UNIQUEness = ''NONUNIQUE''';
open v_cur_get_index for v_sql; -- 打开游标,并且SQL执行结果存放到游标
LOOP
fetch v_cur_get_index into v_index_ddl,v_old_index_name;
exit when v_cur_get_index%notfound; -- 退出循环 -- 为索引取一个名字,名字是随机取得
SELECT dbms_random.string ('x', 8) INTO v_index_name_str FROM dual;
select trunc(dbms_random.value(0,100000)) INTO v_index_name_num from dual;
v_index_name := 'idx_'||v_index_name_str||'_'||to_char(v_index_name_num); -- 把建立索引的语句中的索引名字改掉
SELECT REPLACE(v_index_ddl,
v_old_index_name,
v_index_name)
into v_sql
from dual; --dbms_output.put_line(v_sql);
-- 把建立索引的语句中的表名改掉
SELECT REPLACE(v_sql,
v_base_table_name_upper,
v_new_tableName)
into v_sql
from dual; --dbms_output.put_line(v_sql);
execute IMMEDIATE v_sql; END LOOP; -- 创建索引的动态游标结束
end loop;
end loop;
close v_cur_get_basetable;
end ; -- 查看存储过程是不是有错误
select * from user_errors; -- 执行存储过程
begin
proc_create_monthly_tables;
end; -- 查看效果
SELECT * FROM user_tables WHERE table_name LIKE upper('aa_wanglc_test%');
SELECT * FROM USER_indexes WHERE table_name LIKE upper('aa_wanglc_test%'); -- 删除测试表的语句
select 'drop table '|| table_name || ';' from user_tables where table_name like upper('aa_wanglc_test%');

结果说明
    这个存储过程可以通过一个表来建其他表,并且能建立源表的主键和索引等对象。

在oracle中使用基表建立月表的存储过程的更多相关文章

  1. Oracle中解析XMLType格式字段

    背景:项目从某数据交换平台获取XML数据,以Oracle的XMLType格式保存在数据库字段中,需要建立触发器.存储过程,在保存数据时解析XML字段,将数据写入其他业务表中. 参考资料:Oracle的 ...

  2. Oracle中建立物化视图报错

    Oracle中建立物化视图报错 今天在建立视图的时候,报了一个错:ORA-01723: zero-length columns are not allowed. 建视图的语句: create mate ...

  3. 如何在Oracle中建立表和表空间?

    1.建表空间 ORACLE中,表空间是数据管理的基本方法,所有用户的对象要存放在表空间中,也就是用户有空间的使用权,才能创建用户对象.否则是不充许创建对象,因为就是想创建对象,如表,索引等,也没有地方 ...

  4. ORACLE 中ROWNUM用法总结(转)

    ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...

  5. oracle中imp命令详解 .

    转自http://www.cnblogs.com/songdavid/articles/2435439.html oracle中imp命令详解 Oracle的导入实用程序(Import utility ...

  6. ORACLE 中ROWNUM用法总结!

    ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...

  7. Oracle中的rownum用法解析

    注意:rownum从1开始:  1.rownum按照记录插入时的顺序给记录排序,所以有order by的子句时一定要注意啊!  2.使用时rownum,order by字段是否为主键有什么影响?  3 ...

  8. 转:Oracle中的rownum不能使用大于>的问题

    一.对rownum的说明 关于Oracle 的 rownum 问题,很多资料都说不支持SQL语句中的“>.>=.=.between...and”运算符,只能用如下运算符号“<.< ...

  9. oracle中imp命令具体解释

    oracle中imp命令具体解释 Oracle的导入有用程序(Import utility)同意从数据库提取数据,而且将数据写入操作系统文件.imp使用的基本格式:imp[username[/pass ...

随机推荐

  1. 2.NumPy简介

    一:NumPy简介 • 官网链接:http://www.numpy.org/ • NumPy教程链接:https://www.yiibai.com/numpy/ • NumPy是Python语言的一个 ...

  2. Linux 命令配置IP

    配置静态IP:ip addr add 192.168.18.18/24 dev eth0 启动网卡:ifup eth0/ifup ifcfg-eth0 添加默认网关路由:ip route add de ...

  3. TCP/IP——内网IP

    版权声明:本文系博主原创文章,转载或引用请注明出处. 1)背景 REC 1918留出了3块IP地址空间(1个A类地址段,16个B类地址段,256个C类地址段)作为私有的内部使用的地址. 在这个范围内的 ...

  4. 使用js拆分带参数的URL,将参数分离出来

    url中的内容www.XXXX.com?content=123; 一下为js内容,包装在一个init方法中. init(); function init(){ var theRequest = new ...

  5. hive日期函数-Demo(二)

    需求:某资产近一个月的资产值 比如:今天是2018年2月28日,近一个月若是按照自然月来算,那么是2018年2月1日至2018年2月28日.最终需要的日期格式为:yyyyMMdd. 当日时间戳 uni ...

  6. JAVA 日期操作

    1.用java.util.Calender来实现 Calendar calendar=Calendar.getInstance(); calendar.setTime(new Date()); Sys ...

  7. this 的用法 为原始类型扩展方法

    namespace Demo { public static class Extends { // string类型扩展ToJson方法 public static object ToJson(thi ...

  8. prop(name|properties|key,value|fn)

    prop(name|properties|key,value|fn) 概述 获取在匹配的元素集中的第一个元素的属性值.直线电机选型 随着一些内置属性的DOM元素或window对象,如果试图将删除该属性 ...

  9. jquery fadeOut()方法 语法

    jquery fadeOut()方法 语法 作用:fadeOut() 方法使用淡出效果来隐藏被选元素,假如该元素是隐藏的.大理石平台精度等级 语法:$(selector).fadeOut(speed, ...

  10. Word:表格在页面中垂直居中

    本文适用于Word 2007 + Windows 7,熊猫帮帮主@cnblogs 2018/2/22 如何让表格在页面上垂直居中呢.想当然的认为这属于表格的设置,在表格属性和其它表格相关选项中一通猛找 ...