日期:2014-05-17  浏览次数:20795 次

求oracle插入初始数据pl/sql语句优化
现有一张话务信息表,建表语句如下:
create table VIP_RECKONING
(
  N_ID NUMBER(20) not null,
  PHONE_NUM VARCHAR2(11),
  D_ACCOUNTDATE DATE,
  N_MONTHRENT NUMBER(20,2),
  N_BASERATE NUMBER(20,2),
  N_LONGRATE NUMBER(20,2),
  N_NOTERATE NUMBER(20,2),
  N_RAMBLERATE NUMBER(20,2),
  N_INCREMENTRATE NUMBER(20,2),
  N_OTHERRATE NUMBER(20,2),
  N_PREKEEP NUMBER(20,2),
  N_LIVE NUMBER(20,2)
);
comment on column VIP_RECKONING.N_ID
  is '话务编号';
comment on column VIP_RECKONING.PHONE_NUM
  is '手机号码';
comment on column VIP_RECKONING.D_ACCOUNTDATE
  is '帐期';
comment on column VIP_RECKONING.N_MONTHRENT
  is '月租费';
comment on column VIP_RECKONING.N_BASERATE
  is '基本通话费';
comment on column VIP_RECKONING.N_LONGRATE
  is '长途费';
comment on column VIP_RECKONING.N_NOTERATE
  is '短信费';
comment on column VIP_RECKONING.N_RAMBLERATE
  is '漫游费';
comment on column VIP_RECKONING.N_INCREMENTRATE
  is '增值业务费';
comment on column VIP_RECKONING.N_OTHERRATE
  is '其他费用';
comment on column VIP_RECKONING.N_PREKEEP
  is '预存话费';
comment on column VIP_RECKONING.N_LIVE
  is '余额';


初始化数据要求初始化模拟最近7个月的话务记录。客户手机号码(PHONE_NUM)从另外一张客户表(VIP_CUS_BASEINFO)取得,
客户表有模拟一万个客户.

该表让人纠结的就是一个话费余额字段,初始化时第一个月余额计算教简单,直接用
余额 = 预存话费 - 月租费 - 基本通话费 - 长途费 - 短信费 - 漫游费 - 增值业务费 - 其他费用。

非第一个月余额,还需要加入上个月余额。
余额 = 预存话费 - 月租费 - 基本通话费 - 长途费 - 短信费 - 漫游费 - 增值业务费 - 其他费用 + 上月余额


本人的插入初始化数据存储过程如下:
create or replace procedure thi_pro as
randomnum number;
randomnum2 number;
randomnum3 number;
randomnum4 number;
randomnum5 number;
randomnum6 number;
begin
  for i in REVERSE 1..7 loop
  randomnum:=round(dbms_random.value(0,100));--基本通话费
  randomnum2:=round(dbms_random.value(0,100));--长途费
  randomnum3:=round(dbms_random.value(0,100));--短信费
  randomnum4:=round(dbms_random.value(0,100));--漫游费
  randomnum5:=round(dbms_random.value(0,100));--增值业务费
  randomnum6:=round(dbms_random.value(0,100));--其他费用
   
  insert into VIP_RECKONING select
  seq_VIP_RECKONING.nextval,
  v_phone_num,
  trunc(add_months(sysdate,-i),'MM'),
  10,
  randomnum,
  randomnum2,
  randomnum3,
  randomnum4,
  randomnum5,
  randomnum6,
  650,
  0
  from VIP_CUS_BASEINFO;
   
  if i=7 then 
  update VIP_RECKONING v set v.n_live=800-10-randomnum-randomnum2-randomnum3-randomnum4-randomnum5-randomnum6;
   
  else 
   
  update VIP_RECKONING v set v.n_live=(select 800-10-randomnum-randomnum2-randomnum3-randomnum4-randomnum5-randomnum6+
  v1.n_live from VIP_RECKONING v1 where v1.phone_num=v.phone_num and 
  v1.d_accountdate=trunc(add_months(sysdate,-i-1),'MM')) 
  where v.d_accountdate=trunc(add_months(sysdate,-i),'MM');
   
   
  end if;  
  end loop;
  commit;

end;

该存储过程执行需要很久时间(将近16分钟),应该如何改进,不知各位有何看法。

------解决方案--------------------