一个两层的循环嵌套:一是按通道11~31循环;二是每个通道循环时间(按月)查不同月份的表并合计数量。
通道循环用了for,内嵌直接Loop+if。执行提示在execute immediate处“表或视图不存在”。
【详细代码如下】
【1楼附上指定表及设置outline结果】Create or Replace procedure sp_Rpt_cc365tt
(
       i_sBeginTime in varchar2,
       i_sEndTime in varchar2,
       i_sBeginMonth in varchar2,
       i_sEndMonth in varchar2   
)
AS
       sBeginTime date;
       sEndTime date;
       i NUMBER;
   
   cid_num NUMBER;      --用于循环,从11到31。
   cid_char VARCHAR2(50);  --存储cid值..
   serviceno_num NUMBER(5);    --存储serviceno值..
   sql_serviceno VARCHAR2(50);
   
       sBeginMonth NUMBER;
       sEndMonth NUMBER;
       sIntfor NUMBER;          --月份跨度,依据此来循环查询次数
       sTableName varchar2(20);     --所查询的表名变量,"tbilllog + sMonth"
      sCallinagtNUM NUMBER;   --人工呼入量
       v_numagt number:=0;
       sqlstragt varchar2(1000);   
  
BEGIN /* 删除表数据 */
delete from tRpt_chl365tt;/******************************/
/* 初步转换外部参数及内部变量 */
/******************************/
sBeginTime := to_date(i_sBeginTime, 'yyyymmddhh24miss');
sEndTime := to_date(i_sEndTime, 'yyyymmddhh24miss');
sBeginMonth := to_number(i_sBeginMonth,'99');
sEndMonth := to_number(i_sEndMonth,'99');
sIntfor :=  sEndMonth - sBeginMonth;
/********************/
/* For循环通道11~31 */
/********************/
for cid_num in 11..31 Loop
cid_char := to_char(cid_num,'99');

----chlid、chldep、serviceno sql sentence----
sql_serviceno := '
select serviceno from tRpt_chl365 where cid='||cid_char||'
';
execute immediate sql_serviceno into serviceno_num;/**********************/
/* 月循环 */
/**********************/
i := 0;
--cid_num := 10;  --for use it in 11..31..
Loop
    sTableName := 'tbilllog'|| to_char(sBeginMonth);
    i := i + 1;
    sBeginMonth := sBeginMonth + 1; --放在此处或运算结束/循环结束判断前。
dbms_output.put_line(sTableName);
/* 定义动态SQL语句及计算相关记录数量 */sqlstragt:= '
select count(DISTINCT callid) 
from '||sTableName||'
where CALLEND >= to_date('''||i_sBeginTime||''',''YYYYMMDDHH24MISS'') 
  and 
  CALLEND < to_date('''||i_sEndTime||''',''YYYYMMDDHH24MISS'')
      and
      CALLTYPE in (0,5,13)
  and
  (devicetype = 2 or (devicetype = 1 and callidnum = -1))   --
  and
  SERVICENO='||serviceno_num||'
  and
  (CALLEENO='''||85616666||''' or CALLEENO='''||83508063||''')
' ;execute immediate sqlstragt into sCallinagtNUM;
   v_numagt := v_numagt + sCallinagtNUM; 
/* 插入数据 */
    if i > sIntfor then
       exit;
    end if;
end Loop;   --退出月循环.以i计数..insert into 
       tRpt_chl365tt(...)  values (...);/* 退出循环 */
    
end Loop;  --退出for cid_num in 11..31 Loop..

解决方案 »

  1.   

    指定sql语句中的表为tbilllog3,设置dbms_output.put_line(sTableName);执行结果,exec SP_RPT_CC365TT('20100323000000','20100324000000','3','3');
    select * from tRpt_chl365tt;
    billlog3
    tbilllog4
    tbilllog5
    tbilllog6
    tbilllog7
    tbilllog8
    tbilllog9
    tbilllog10
    tbilllog11
    tbilllog12
    tbilllog13
    tbilllog3
    tbilllog4
    tbilllog5
    tbilllog6
    tbilllog7
    tbilllog8
    tbilllog9
    tbilllog10
    tbilllog11
    tbilllog12
    tbilllog13
    tbilllog3
    tbilllog4
    tbilllog5
    tbilllog6
    tbilllog7
    tbilllog8
    tbilllog9
    tbilllog10
    tbilllog11
    tbilllog12
    tbilllog13
    tbilllog3
    tbilllog4
    tbilllog5
    tbilllog6
    tbilllog7
    tbilllog8
    tbilllog9
    tbilllog10
    tbilllog11
    tbilllog12
    tbilllog13
    tbilllog3
    tbilllog4
    tbilllog5
    tbilllog6
    tbilllog7
    tbilllog8
    tbilllog9
    tbilllog10
    tbilllog11
    tbilllog12
    tbilllog13
    tbilllog14
    tbilllog15
    tbilllog16
    tbilllog17
    tbilllog18
    tbilllog19
    tbilllog20
    tbilllog21
    tbilllog22
    tbilllog23
    PL/SQL procedure successfully completed.
    【以及一个计算不准确的数据--表tRpt_chl365tt中数据】
      

  2.   

    你先可以在plsql dev中单步调试执行一下
    或者你保存一个这个sqlstragt的拼接串到数据库的一个临时表中
    如:create table temp_sqlstr(table_name varcahr2(50),sqlstr long);
    在execute immediate 语句前增加
    insert into temp_sql values(sTableName,sqlstragt);
    commit;然后再检查一个这些SQL
      

  3.   

    还有,楼主的sql拼接,最好写成
    sqlstragt := 'select .....';
    sqlstragt := sqlstragt + 'where .....';
    这种形式,这样代码好读一些,便于调试