以下代码,循环查表数据插入表中,但是插入表的数据参数值都累加在最后,前面的都是0,不明原因,求救:((): --Create or Replace procedure sp_Rpt_counti3pH
/* ******** ********
 spTEST9_2:加1小时循环,判断月最后一天比较以月份+1组合表名,以及是否为sEndTime以退出。091116.
******** ******** */
(
       i_sBeginTime in varchar2,
       i_sEndTime in varchar2,
       i_sBeginMonth in varchar2,
       i_sEndMonth in varchar2 
)
AS
       sBeginTime date;
       sEndTime date;
       i NUMBER;           --月循环累加次数
   
       sBeginMonth NUMBER;
       sEndMonth NUMBER;
       sIntfor NUMBER;          --月份跨度,依据此来循环查询次数(作为月循环比较数)
       sTableName varchar2(20);     --所查询的表名变量,"tbilllog + sMonth".    ssDateTimeB date; --作为新的时间条件,取代sBeginTime
   ssDateTimeE date; --作为新的时间条件,取代sEndTime       sCallinNUM NUMBER;     --呼入量
       sqlstr varchar2(1000); --呼入量统计SQL。
   sCalledNUM NUMBER;   --接通量
       sqlstrCalled varchar2(1000);   --接通量统计SQL。
   sCalledRATE NUMBER(12,4);   --接通率
   sCalllostNUM NUMBER;   --呼损量
   sCalllostRATE NUMBER(12,4);   --呼损率
   
BEGIN/******************************/
/* 初步转换外部参数及内部变量 */
/******************************/
sBeginTime := to_date(i_sBeginTime, 'yyyymmddhh24miss');
sEndTime := to_date(i_sEndTime, 'yyyymmddhh24miss');
sBeginMonth := to_number(i_sBeginMonth,'99');
sEndMonth := to_number(i_sEndMonth,'99');ssDateTimeB := sBeginTime; --初始查询日期开始时间delete from tRpt_CrmTmp3p;    --初始表处理: 删除表数据
/**************************/
/* 循环开始运算/查询/统计 */
/**************************//* 循环开始 */
i := 0;
Loop
    i := i+1;
    sTableName := 'tbilllog'|| to_char(sBeginMonth); --组合表名。
ssDateTimeE := ssDateTimeB + 1/24; --初始查询日期结束时间
/* 定义动态SQL语句及计算相关记录数量 */
----呼入量----
sqlstr:= '
select count(DISTINCT callid) 
from '||sTableName||'
where CALLEND >= '''||ssDateTimeB||''' 
  and 
  CALLEND < '''||ssDateTimeE||'''
      and
      CALLTYPE in (0,5,13)
  and
  (CALLEENO='''||88880000||''' or CALLEENO='''||88881111||''')
' ;
----接通量----
sqlstrCalled:= '
select count(DISTINCT callid) 
from '||sTableName||'
where CALLEND >= '''||ssDateTimeB||''' 
  and 
  CALLEND < '''||ssDateTimeE||'''
      and
      CALLTYPE in (0,5,13)
  and
  WAITEND-WAITBEGIN+ACKEND-ACKBEGIN+CALLEND-CALLBEGIN>0        --恢复原计算方法091104.
  and
  (CALLEENO='''||85616666||''' or CALLEENO='''||83508063||''')
' ;
/* 执行动态SQL语句 */
----呼入量----
execute immediate sqlstr into sCallinNUM;
----接通量----
execute immediate sqlstrCalled into sCalledNUM;----呼损量----
sCalllostNUM := sCallinNUM - sCalledNUM;----接通率----
select NVL(DECODE( sCallinNUM,
                   0,
                0,
                (sCalledNUM / sCallinNUM) * 100), 0)
into sCalledRATE from dual;----呼损率----
select NVL(DECODE( sCallinNUM,
              0,
              0,
              (sCalllostNUM / sCallinNUM) * 100), 0)
into sCalllostRATE from dual;
/***********************/
/* tRpt_CrmTmp3p表处理 */
/***********************//* 插入数据 */
insert into 
       tRpt_CrmTmp3p(cBeginTime, cEndTime, cCallinNUM, cCalledNum)
       values (ssDateTimeB, ssDateTimeE, sCallinNUM, sCalledNUM);
/*****************************/
/* 循环结束判断以下一循环运算 */
/******************************//* 判断加月或下一小时运算处理以及运算下一次循环基础数据 */
--判断累加的ssDateTimeE为月最后一天,是则月份+1供组合表名
    if ssDateTimeE = (last_day(ssDateTimeB) + 1/24) then --本次结束时间为本地开始时间的月最后一天加1小时
       sBeginMonth := sBeginMonth + 1; --开始月份加一月,进入下一次月循环的表名组成之月份部分。
    end if;    ssDateTimeB := ssDateTimeB + 1/24;   --初始化ssDateTimeB.

--然后判断ssDateTimeE为sEndTime则退出
    if ssDateTimeE = sEndTime then
       exit;
    end if;
end Loop;
/* 循环结束 */END sp_Rpt_counti3pH; 
执行: exec SP_RPT_COUNTI3PH('20090701000000','20090702000000','7','7');
select * from tRpt_CrmTmp3p;
select to_char(cbegintime, 'yyyymmddhh24miss'),to_char(cendtime, 'yyyymmddhh24miss'),ccallinnum,ccallednum from tRpt_CrmTmp3p;
结果: 20090701000000 20090701010000 0 0
20090701010000 20090701020000 0 0
……
20090701220000 20090701230000 0 0
20090701230000 20090702000000 43196 43193

解决方案 »

  1.   

    所有字段…… 
    我原本是要查询每个小时的count数据插入到表中
    但是这个代码的“结果”,前23小时的都是0,到第24小时,是累积的值插入到表中了。
      

  2.   

    发现一个地方,最后一个有记录是因为
    CALLEND >= to_date('20090701230000','yyyymmddhh24miss')
          and 
          CALLEND <  to_date('20090702000000','yyyymmddhh24miss') 你测试一下
    CALLEND >= to_date('20090701010000','yyyymmddhh24miss')
          and 
          CALLEND <  to_date('20090701010000','yyyymmddhh24miss') 看看是否能查出记录
      

  3.   

    或者
    to_char(CALLEND,'yyyymmddhh24miss') >= '20090701230000' and ..
      

  4.   

    我抽取了一些时间段如:select count(DISTINCT callid) 
    from tbilllog7
    where CALLEND >= to_date('20090701000000','YYYYMMDDHH24MISS') 
      and 
      CALLEND < to_date('20090701010000','YYYYMMDDHH24MISS')
          and
          CALLTYPE in (0,5,13)
      and
      (CALLEENO='85616666' or CALLEENO='83508063')
    ;
    select count(DISTINCT callid) 
    from tbilllog7
    where CALLEND >= to_date('20090701000000','YYYYMMDDHH24MISS') 
      and 
      CALLEND < to_date('20090702000000','YYYYMMDDHH24MISS')
          and
          CALLTYPE in (0,5,13)
      and
      (CALLEENO='88880000' or CALLEENO='88881111')
    ;结果如下:COUNT(DISTINCTCALLID)
    ---------------------
                       27
    1 row selected.COUNT(DISTINCTCALLID)
    ---------------------
                    43196
    1 row selected.
      

  5.   

    我执行存储过程,改成两天的时候exec SP_RPT_COUNTI3PH('20090701000000','20090703000000','7','7');
    结果如下,两天都是最后一组累加的数据,理解不到:(  20090701000000 20090701010000 0 0
    ……
    20090701220000 20090701230000 0 0
    20090701230000 20090702000000 43196 43193
    20090702000000 20090702010000 0 0
    ……
    20090702220000 20090702230000 0 0
    20090702230000 20090703000000 29047 29042
      

  6.   

    在過程裏面加一些dbms output輸出查看關鍵值的變化
      

  7.   

    dbms_output.put_line(sCallinNUM);
    前面23小时果然是0
    第24小时的是合计值
    奇怪,为什么会这样呢?
      

  8.   


       scDateTimeB varchar2(20);
       scDateTimeE varchar2(20);
    --……
    scDateTimeB := to_char(ssDateTimeB,'YYYYMMDDHH24MISS');
    scDateTimeE := to_char(ssDateTimeE,'YYYYMMDDHH24MISS');
    --……
    where CALLEND >= to_date('''||scDateTimeB||''',''YYYYMMDDHH24MISS'') 
      and 
      CALLEND < to_date('''||scDateTimeE||''',''YYYYMMDDHH24MISS'')很奇怪很奇怪。从date转换成char,再在查询条件里将char转换成date就可以了!!!
      

  9.   

    原因是,动态语句,
    动态语句中ssDateTimeB和ssDateTimeE两个变量多了一对单引号如果不做转换,只需把动态语句中的
    CALLEND >= '''||ssDateTimeB||''' 
    改为
    CALLEND >= '||ssDateTimeB||'
    其他地方也是,因为多加了一对单引号,导致这两个date类型的值被当成了varchar类型,这个时候条件比较的时候出了问题。一直关注你的sql,忘记查看过程了。