由于单表数据量太大,达到千万级别,所以考虑采用oracle的存储过程实施分表操作。
说明:schema表中存储指标信息
store表中存放schema中指标指定的存储信息
dic_info是字典表
按照schema的id号建相同表结构的表,更新字典项,把原始的大表里的数据分摊到新建的小表中,实现分表。
create or replace procedure PROC_CREATE_TABLE_INSERT_DATA
(
--用以输出的信息
on_flag out number, --SQL错误码
out_reason out varchar2 --错误原因
)
is
v_table_name varchar2(50); --新生成的数据表表名
v_table_num integer; --数据表的数据量
v_create_sql varchar2(768); --建表语句
v_data_insert varchar2(256); --数据插入语句
v_old_table varchar2(50); --原始表表名
v_dic_sql varchar2(128); --字典项查询语句
v_dic_count integer; --字典项记数
v_data_count_sql varchar2(128); --数据统计语句
v_data_count integer; --数据记数
begin
--schema表中的数据存储信息放在store表中,而store表中的表id号是存储在字典表dic_info中的,现在将schema id作为新的表名,原始存储表名作为旧的表名
--oracle循环查询的结果集到v_schemas变量中
for v_schemas in (select a.id as newTable, c.code as oldTable
from schema a, store b, dic_info c
where b.tablenameid =
c.id and a.storeid = b.id) loop
v_table_name :=
v_schemas.newTable; --oracle数据复制给变量
v_old_table :=
v_schemas.oldTable;
--检测是否已存在要建的表
select count(*) into v_table_num from user_tables where table_name = upper(v_table_name);
if (v_table_num < 1) then
v_create_sql := 'create table '|| v_table_name || '(
id VARCHAR2(50) primary key,
schemaid VARCHAR2(50),
columnvalue1 VARCHAR2(128),
columnvalue2 VARCHAR2(128),
columnvalue3
VARCHAR2(128)
)';
--建表
execute immediate v_create_sql;
commit;
dbms_output.put_line('新建表:' || v_table_name || ' 成功。'); --输出记录
--更新dic_info中的表信息
v_dic_sql := 'select count(*)
from dic_info where code = ' || chr(39) || v_table_name ||
chr(39);
execute immediate v_dic_sql into v_dic_count;
if (v_dic_count < 1) then
insert into dic_info
-- select sys_guid() from dual 是oracle中新建GUID的方式
values ((select sys_guid() from dual), v_table_name, v_table_name,
'48484a2730b1703c0130b5651e9a001e', null, 0, null, null);
commit;
end if;
--将原始数据表中的采集数据导入新建表
--oracle中chr(39)表示单引号
v_data_insert := 'insert into ' || v_table_name || ' (select * from ' || v_old_table || ' where schemaid = ' || chr(39)|| v_table_name ||
chr(39) || ')';
v_data_count_sql := 'select count(*)
from ' ||
v_table_name;
--由于v_table_name是动态生成的,所以需要用execute去执行
execute immediate v_data_count_sql into v_data_count;
if (v_data_count < 1) then
execute immediate v_data_insert;
commit;
execute immediate v_data_count_sql into v_data_count;
dbms_output.put_line('向表' || v_table_name || '中存入数据' || v_data_count || '条');
end if;
--更新存储定义
update store a set a.tablenameid = (select id from dic_info where name = v_table_name)
where id = (select storedeid from schema where id = v_table_name);
commit;
else
dbms_output.put_line('指定表:' || v_table_name || ' 已存在。');
end if;
end loop;
--处理异常
EXCEPTION
WHEN OTHERS THEN
on_flag := SQLCODE;
out_reason := SUBSTR (SQLERRM, 1, 255);
ROLLBACK;
end;
PS:在存储过程执行过程中抛出
ORA-20000: buffer overflow, limit of 10000 bytes异常,
是因为有dbms_output.put_line语句,在pl/sql脚本中执行
SQL> set serveroutput 100000;
也不行。后来改为Test时手动修改 Buffer si的容量后才没有报错。
- 大小: 6.8 KB
分享到:
相关推荐
1、修改表名 2、创建新表 3、按时间条件插入数据 由于数据太大、用的改表名的方式备份分表,通过传入表名和条件字段名备份相应的表
资源里包含SQL文档:创建数据库和存储过程.sql 生成数据.sql 测试.sql 比较完善的大量数据分表功能代码,包含创建数据库、生成数据、测试结果。适合初学分表者使用。 数据按照每个月创建一个数据表,通过存储过程...
主要技术有: springboot shardingsphere swagger mybatis-plus mysql
sharind-jdbc样例,当中包含了按月动态分表,一个比较简单的demo,仅供参考!
MySQL动态创建表,数据分表的存储过程,需要的朋友可以参考下。
利用MybatisPlus来实现对表的水平分表,全自动,可以首先判断表是否存在,不存在创建表,然后设计有定时任务,可以每个月月末的时候,去创建下一个分表程序
杰奇小说系统分站分表手机版模板,支持分表、多站点
sharind-jdbc样例,当中包含了按月动态分表,一个比较简单的demo,大家可以结合自己的需求进行修改,以及可以看下实现思路,仅供参考!
- 分表情况,2:日期分表,按照目标表里面的记录日期的字段,按照日期【日、周、月、年】拆分成多个表【本代码仅考虑unix时间戳来分表,其它不支持,您可以自己思考,自己修改代码】 - 注意,支持【子表】,填入...
一个简单的oracle数据库环境下的存储过程,介绍了如何从带年月人的分表取数据
基于ShardingSphere实现的动态数据库+自动按月分表、建表框架。
kettle对数据分表插入 数据库Oracle etl工具 kettle 通过java脚本,hash算法,实现分表数据写入
MySQL分表及分表后插入sql语句,表为订单表,可以参考一下
分表 JAVA 分表例子,带SQL文件 很简单的例子,就可以明白怎么分表。
SQL,大数据分表,SQL千万级分表,删除百万数据
水平拆分数据分库和分表的核心问题是表的ID唯一,然后根据唯一的ID映射到一个物理存储位置,这个映射方案要考虑到满足数据量暴增线性扩展和业务上容易保持一致,本文主要讨论分库分表如何映射的问题。
sharding-jdbc 分库分表 CRUD
Java+Springboot+mybatis+sharding jdbc 实现分库分表
数据库分库分表 数据库分库分表 数据库分库分表
解决大数据量存储时,分表存储时常见问题及解决方案