上周有新需求把face++识别的身份证信息存到会员中。存量数据还有1300万数据,也就是要刷1300万的数据。
想过跑批查询封装多线程调用dubbo接口,怕dubbo服务提供者扛不住。
考虑走脚本刷,一条脚本如下:
update mem.mem_base_info i
set i.nation = decode(i.nation,
null,
(select nation
from risk.loan_identity_personinfo p
where i.cust_id = p.mid),
i.nation),
i.police_station = decode(i.police_station,
null,
(select id_org
from risk.loan_identity_personinfo p
where i.cust_id = p.mid),
i.police_station),
i.id_validity_date = decode(i.id_validity_date,
null,
(select case length(p.id_effect_date)
when 21 then
to_date(substrb(p.id_effect_date,
12),
'yyyy.mm.dd')
else
null
end
from risk.loan_identity_personinfo p
where i.cust_id = p.mid),
i.id_validity_date),
i.id_address = decode(i.id_address,
null,
(select id_address
from risk.loan_identity_personinfo p
where i.cust_id = p.mid),
i.id_address),
i.update_time = sysdate
where i.cust_id = 3800000273511449;
找dba刷数据,dba说:“你这样的数据刷不了,执行太慢了。 ”,我说:“写个存储过程刷”,dba说“我不会这么玩!”,听完内心千万头羊驼飞奔而去,只好自己写存储过程,庆幸之前有一份存储过程的脚本,拿来借鉴。
存储过程v1版
create or replace procedure proc_update_meme_id_card_info is
i number;
begin
--初始值
i := 0;
--循环到结束
while i < 850 loop
--循环update 1天的数据
for x in (select mid,nation,
case length(p.id_effect_date)
when 21 then
to_date(substrb(p.id_effect_date, 12), 'yyyy.mm.dd')
when 17 then
to_date(substrb(p.id_effect_date, 10), 'yyyymmdd')
else null end as id_effect_date,
id_address, id_org from risk.loan_identity_personinfo p where trunc(p.update_time) = trunc(sysdate - i)) loop
update mem.mem_base_info i
set i.nation = decode(i.nation, null, x.nation, i.nation),
i.police_station = decode(i.police_station, null,x.id_org,i.police_station),
i.id_validity_date = decode(i.id_validity_date, null, x.id_effect_date, i.id_validity_date),
i.id_address = decode(i.id_address, null, x.id_address, i.id_address),
i.update_time = sysdate where i.cust_id = x.mid;
commit;
end loop;
Dbms_Output.put_line( ' i : ' || i);
i := i + 1;
end loop;
end proc_update_meme_id_card_info;
执行发现时间的垃圾数据太多,正常的情况:2010.01.02-2020.01.02 或者 2010.01.02-长期 或者 20100102-20200102 结果数据库里面有 2010.01.02-20.2001.02 垃圾数据,要忽略处理,懵~~~
后来想想存储过程可以出现异常信息然后忽略的,出了v2版
create or replace procedure proc_update_meme_id_card_info is
i number;
begin
--初始值
i := 0;
--循环到结束
while i < 850 loop
--循环update 1天的数据
for x in (select mid,nation,
case length(p.id_effect_date)
when 21 then
to_date(substrb(p.id_effect_date, 12), 'yyyy.mm.dd')
when 17 then
to_date(substrb(p.id_effect_date, 10), 'yyyymmdd')
else null end as id_effect_date,
id_address, id_org from risk.loan_identity_personinfo p where trunc(p.update_time) = trunc(sysdate - i)) loop
update mem.mem_base_info i
set i.nation = decode(i.nation, null, x.nation, i.nation),
i.police_station = decode(i.police_station, null,x.id_org,i.police_station),
i.id_validity_date = decode(i.id_validity_date, null, x.id_effect_date, i.id_validity_date),
i.id_address = decode(i.id_address, null, x.id_address, i.id_address),
i.update_time = sysdate where i.cust_id = x.mid;
commit;
end loop;
Dbms_Output.put_line( ' i : ' || i);
i := i + 1;
end loop;
end proc_update_meme_id_card_info;
编译成功!大功告成
执行存储过程
begin
-- Call the procedure
proc_update_meme_id_card_info;
end;
存储过程写法:
CREATE OR REPLACE PROCEDURE 存储过程名(param1 in type,param2 out type)
IS
变量1 类型(值范围);
变量2 类型(值范围);
BEGIN
select count(*) into 变量1 from 表名 where 列名=param1;
if (判断条件) then
select 列名 into 变量2 from 表名 where 列名=param1;
DBMS_OUTPUT.put_line('打印信息');
Elsif (判断条件) then
dbms_output.put_line('打印信息');
Else
Raise 异常名 (NO_DATA_FOUND);
End if;
Exception
When others then
Rollback;
END;