面对开源的世界...
如果你追求阳光,就躲不开身后的身影。
posts - 115,comments - 87,trackbacks - 0

需求描述

输入参数:cpid,业务能力

根据用户号码文件把指定sp的业务能力(本工具只针对SMS)下定购关系删除,不管定购关系处于什么状态。并记录日志,以便以后备查。如果用户信息不存在则不处理。

工具支持aix,linux上的oracle数据库, 执行者:运营商管理员。

程序流程:执行linux for suse下的shell脚本调用sqlload将用户文件数据导入临时表zxdbm_ismp.file_usercode,再利用shell调用Oracle存储过程,根据外部入参和临时表记录对订购关系相关表记录进行批量删除。删除过程涉及到的表有:zxdbm_ismp.s200_user_subscription,zxdbm_ismp.ssrv_user_totalamount和zxdbm_ismp.ssrv_user_totalamount01到zxdbm_ismp.ssrv_user_totalamount12(共12张表,根据当前月份删除对应月份表)。

技术实现:采用游标对临时表zxdbm_ismp.file_usercode循环扫描,并结合入参cpid,srvtypeshortname(业务能力)对相关业务表进行记录删除。

shell实现在此省略,具体实现可以参考:  http://www.blogjava.net/cheneyfree/archive/2007/12/01/164476.html

存储过程实现如下:(针对当月的累计记录删除运用动态SQL大大减少了工具的代码量)


CREATE OR REPLACE PROCEDURE delete_user_subscription
(
   v_spid 
varchar2,
   v_srvtypeshortname 
varchar2,   --业务能力名
   v_retvalue  out varchar2 
)
AS
   v_userindex 
number;
   v_curdate 
varchar(40) := to_char(sysdate ,'yyyymmddhh24miss');  --当前时间
   v_servicetype number;
   v_cpindex 
number;   
   v_table_totalamount 
varchar2(100); --累计表名
   str_sql varchar2(1000);
   
   v_curmonth 
number;
   v_message 
varchar2(1000);
   v_usercode 
varchar2(100);
   
   countnum 
number := 1;
   
   type ref_cursor_type 
is REF CURSOR;
   cursor_select   ref_cursor_type;
   select_cname  
varchar2(1000);
begin
  v_curmonth :
= lpad(to_number(substr(v_curdate,5,2)),2,'0');--月份2位,不足前补0,lpad函数转换大写
  v_table_totalamount := 'zxdbm_ismp.ssrv_user_totalamount' || v_curmonth; --动态获得累计表名    
  
  
--SMS  
  if(upper(v_srvtypeshortname) = 'SMS'then 
      v_servicetype :
= 1;                       
  
--srvtypeshortname为空或不存在
  else
      v_retvalue :
='srvtypeshortname is not exist,please try again!'
      
return;  
  
end if;
  
  
begin
        
--获得cpindex
        select cpindex into v_cpindex from zxdbm_ismp.scp_basic where cpid = v_spid;  
  exception 
when others then
        
--入参数spid为空或无效(查询不到cpindex)
        v_message := sqlcode ||':'|| sqlerrm;
        
insert into zxdbm_ismp.log_delete values(v_spid,v_usercode,v_srvtypeshortname,sysdate,v_message||'------'||'not find cpindex from scp_basic with spid!');  
        
commit;
        v_retvalue :
='not find cpindex from scp_basic with spid,please try again!';
        
return;
  
end;
  
  select_cname :
= 'select usercode from zxdbm_ismp.file_usercode';
  
Open  cursor_select For select_cname;
  
Fetch cursor_select into v_usercode;
  
While cursor_select%Found Loop
  
--当循环到大于10000时,commit掉缓冲区中的数据,同时countnum归1
  if countnum > 10000 then
        
begin
            
commit
            countnum :
= 1;                   
        
end;
  
end if;
  
begin
        
--获得userindex  select条件不满足转异常
        select userindex into v_userindex from zxdbm_ismp.susr_basic where usercode = v_usercode;
  exception 
when others then
        
--不存在的号码insert到log_delete
        v_message := sqlcode ||':'|| sqlerrm;
        
insert into zxdbm_ismp.log_delete values(v_spid,v_usercode,v_srvtypeshortname,sysdate,v_message||'------'||'this usercode is invalid!');  
        
commit;
        
--异常后定位至下一个号码
        goto next_home;
  
end
  
begin
        
delete from zxdbm_ismp.ssrv_user_totalamount where userindex = v_userindex and cpindex = v_cpindex and servicetype = v_servicetype and amounttype <> 8;
        
--订购关系记录先备份后删除
        if(v_servicetype = 1then 
          
--当select条件不满足转异常
          insert into zxdbm_ismp.log_sms_user_subscription (select * from zxdbm_200.s200_user_subscription where cpid = v_spid and usercode = v_usercode and servicetype = v_servicetype);
          
--delete条件不满足时不转异常
          delete from zxdbm_200.s200_user_subscription where cpid = v_spid and usercode = v_usercode and servicetype = v_servicetype; 
          
--删除当前月份的累计记录           
          str_sql:='delete from'||' '||v_table_totalamount||' '||'where userindex =:userindex and cpindex =:cpindex and servicetype =:servicetype and amounttype <> 8';
          
execute immediate str_sql using v_userindex,v_cpindex,v_servicetype;         
        elsif(v_servicetype 
= 2then
           
null;                                
        
else
           
null
        
end if;
        
commit;    
  exception 
when others then
        
rollback;
        v_message :
= sqlcode ||':'|| sqlerrm;
        
insert into zxdbm_ismp.log_delete values(v_spid,v_usercode,v_srvtypeshortname,sysdate,v_message||'------'||'sql exception!');  
        
commit;
        
goto next_home;
  
end
  countnum :
= countnum + 1;
  
<<next_home>>
  
Fetch cursor_select into v_usercode;
  
End Loop;
  
Close cursor_select;
  
  
begin
    loop
    
--每次将中间表v3_sub_1删除10000条记录
      delete from zxdbm_ismp.file_usercode where rownum < 5000;
      
commit;
    
exit when sql%rowcount =0;
      
end loop;
  exception 
when others then
    
rollback;
    v_message :
= sqlcode||':'||sqlerrm;
    
--将某个时间delete中间表中的用户号码记录时出现异常
    insert into zxdbm_ismp.log_delete values(' ',' ',v_srvtypeshortname,sysdate,v_message||'------'||'delete temp table log_delete exception!'); 
    
commit;
  
end
  
  v_retvalue :
='produce is end!';
end ;
posted on 2007-12-19 15:04 cheng 阅读(965) 评论(0)  编辑  收藏 所属分类: OracleUnix/Linux



标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-05-08 13:39 编辑过