一个两层的循环嵌套:一是按通道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..
通道循环用了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..
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中数据】
或者你保存一个这个sqlstragt的拼接串到数据库的一个临时表中
如:create table temp_sqlstr(table_name varcahr2(50),sqlstr long);
在execute immediate 语句前增加
insert into temp_sql values(sTableName,sqlstragt);
commit;然后再检查一个这些SQL
sqlstragt := 'select .....';
sqlstragt := sqlstragt + 'where .....';
这种形式,这样代码好读一些,便于调试