更新表所有id的存储过程
来源:互联网 发布:java 实现 ping ip 编辑:程序博客网 时间:2024/06/03 19:22
最近公司交给我一个任务,他们不小心删除了一个表空间的数据,现在要做数据恢复,本来是资深DBA应该做的事情,现在压到我身上,我才来1个月。不说废话了。
任务1:把一个有9亿条数据的表的id都增加到1000000000000000以后,说简单一点就是更新这个表所有的id字段,
刚拿到这个任务觉得如此简单啊“不就是一个update”就能搞定的事情吗?,下来细想,如果用update,那么我可能明天就开始找新工作了。
因为Oracle数据库有undo段,专门用于存储要rollback的数据,而且空间有限,不能存储这么多的数据量.而且update9Y条数据,那么这个事务有多大呢?在中途断了之后数据就会处于一种未知的状态,简单说:数据库出问题了。
解决方案:最后写了一个存储过程来解决。找到最大的id,找到最小的id,用between来做,每10W条数据提交一次。
存储过程与相关内容如下:
1.首先需要在需要操作的数据库中建如下表:DDL如下:-- Create table
create table INSERT_LOG_EXPECTION(
start_id NUMBER(19),
end_id NUMBER(19),
error_code VARCHAR2(4000),
err_message VARCHAR2(4000),
info VARCHAR2(50)
)
2.创建相关procedure如下
create or replace procedure add_id_histplateinfonew_pro(current_add_number number,number_each_submit number)
as
executeNumber number(20) :=0;--当前id
dataCountMax number(20);
v_current_count_start number(20);
v_current_count_end number(20);
err_code varchar(4000);
err_message varchar(4000);
info varchar(20);
begin
select max(id) into dataCountMax from hist_plateinfo_new;
select min(id) into executeNumber from hist_plateinfo_new;
while executeNumber<= dataCountMax
loop
begin
update hist_plateinfo_new set id = id+current_add_number where id between executeNumber and executeNumber+number_each_submit;
commit;
exit when executeNumber >= dataCountMax;
executeNumber := executeNumber+number_each_submit;
if executeNumber>dataCountMax
then
begin
executeNumber :=dataCountMax;
end;
end if;
end;
end loop;
exception when others then
rollback;
v_current_count_start :=executeNumber;
v_current_count_end :=executeNumber+number_each_submit;
err_code :='更新'||v_current_count_start||'->'||v_current_count_end||'id失败';
err_message :=sqlerrm;
info :='已回滚';
insert into insert_log_expection values(v_current_count_start,v_current_count_end,err_code,err_message,info);
commit;
end;
as
executeNumber number(20) :=0;--当前id
dataCountMax number(20);
v_current_count_start number(20);
v_current_count_end number(20);
err_code varchar(4000);
err_message varchar(4000);
info varchar(20);
begin
select max(id) into dataCountMax from hist_plateinfo_new;
select min(id) into executeNumber from hist_plateinfo_new;
while executeNumber<= dataCountMax
loop
begin
update hist_plateinfo_new set id = id+current_add_number where id between executeNumber and executeNumber+number_each_submit;
commit;
exit when executeNumber >= dataCountMax;
executeNumber := executeNumber+number_each_submit;
if executeNumber>dataCountMax
then
begin
executeNumber :=dataCountMax;
end;
end if;
end;
end loop;
exception when others then
rollback;
v_current_count_start :=executeNumber;
v_current_count_end :=executeNumber+number_each_submit;
err_code :='更新'||v_current_count_start||'->'||v_current_count_end||'id失败';
err_message :=sqlerrm;
info :='已回滚';
insert into insert_log_expection values(v_current_count_start,v_current_count_end,err_code,err_message,info);
commit;
end;
3.执行存储过程语句说明:在plsql中执行为begin add_id_histplateinfonew_pro(需要加的序列值如:(999999999999999999900000000000),每多次个值提交一次(建议10W提交一次));
说明:用到while,exception when,变量定义,参数传递,if,loop等知识。
在cmd 环境下执行存储过程:exec add_id_histplateinfonew_pro(需要加的序列值如:(999999999999999999900000000000),每多次个值提交一次(建议10W提交一次));
任务已经完成,9亿数据,没有出现任何问题。
后续还有很多导出导入工作,自己也偏数据库,这也是一次锻炼的机会,好好把握。
0 0
- 更新表所有id的存储过程
- 更新数据库所有表及所有字段的存储过程
- 更新数据库中表、存储过程或者所有对象的所有者
- SQL Server修改表结构后批量更新所有视图的存储过程
- 通用获取父节点/子节点/子节点下所有节点ID的存储过程
- 通用获取父节点/子节点/子节点下所有节点ID的存储过程
- MySQL存储过程之计算某列值之和小于固定值的所有累加行ID
- oracle存储过程 更新表的排序
- Oracle中用sql查询获取数据库的所有触发器,所有存储过程,所有视图,所有表
- oracle存储过程——按id更新相关信息
- SQL 存储过程 通过多个ID更新数据
- 用存储过程获得表的自定义ID
- 删除所有表,所有试图,所有序列,所有存储过程
- 检查更新的存储过程
- 查询所有表 表的所有列 与表相关的所有视图、存储过程、函数
- 产生自增长ID的存储过程
- 更新所有指定表时间字段及增加一天存储过程
- 更改数据库所有表的所属用户的存储过程
- Ajax提高篇(2)DOM进行Web响应
- Python多进程编程
- c/c++ 取得当前目录
- android studio 导入源码
- 第五周第三天
- 更新表所有id的存储过程
- HDU-4762 Cut the Cake
- A,B两个整数集合,设计一个算法求他们的交集,尽可能的高效(牛客网)
- Socks协议
- Product of Array Except Self
- Spark-1.4.0单机部署(Hadoop-2.6.0采用伪分布式)【已测】
- Linux下如何搭建WEB服务器教程(apach)
- Python多进程编程
- MYSQL 字符集 & 校验规则