oracle pipelined返回值函數 針對數據彙總統計 返回結果集方法

近期須要一個彙總統計,因爲數據太多,數據量太大因此在java程序中實現比較困難。若用後臺程序統計,數據不能保證明時,同時實現週期比較長。顧使用函數返回結果集的方式,在 不增長臨時表的狀況下實時獲取數據。需求爲:多個端口流量每五分鐘累計彙總一次。若是用程序實現則爲講全部數據取出作每五分鐘統計,元數據獲取帶來的數據量將是10萬條以上。
在數據庫中作彙總統計只須要24*12=288條記錄。
具體實現方式以下:
/*打開日誌輸出*/
 
Set serveroutput on ;
 
/*建立類型*/
 
create or replace type type_flux_data_stat_o as object
 
(
 
ifinoctetsbps number ,
 
ifoutoctetsbps number ,
 
collecttime number
 
);
 
/*建立類型歸屬爲表類型*/
 
create or replace type type_flux_data_stat as table of type_flux_data_stat_o;
 
/*pipelined建立函數 返回表類型*/
 
create or replace FUNCTION f_linkgroupstat(begin_time IN NUMBER,
 
end_time IN NUMBER,
 
lg_id in varchar2,
 
table_name varchar2 )
 
return type_flux_data_stat
 
pipelined as
 
/*遊標申明*/
 
v_Cur SYS_REFCURSOR ;
 
/*sql臨時變量*/
 
v_SQLStatement string (10000 );
 
/*表類型*/
 
v_Table type_flux_data_stat_o;
 
/*流入字節數臨時變量*/
 
tmp_ifinoctetsbps NUMBER ;
 
/*流出字節數臨時變量*/
 
tmp_ifoutoctetsbps NUMBER ;
 
/*流入字節數彙總*/
 
total_ifinoctetsbps NUMBER ;
 
/*流出字節數彙總*/
 
total_ifoutoctetsbps NUMBER ;
 
/*起始時間窗格*/
 
tmp_begin_time NUMBER ;
 
/*結束時間窗格*/
 
tmp_end_time NUMBER ;
 
begin
 
/*時間窗格偏移量爲5分鐘(300秒)*/
 
tmp_begin_time := begin_time;
 
tmp_end_time := begin_time + 300 ;
 
total_ifinoctetsbps := 0 ;
 
total_ifoutoctetsbps := 0 ;
 
loop
 
exit when tmp_begin_time > end_time;
 
v_SQLStatement := 'select sum(ifinoctetsbps) ifinoctetsbps,sum(ifoutoctetsbps) ifoutoctetsbps from ' ||
 
table_name ||
 
' a where exists (select 1 from tm_linkgroup_cportdirection b where a.getway = b.getway and a.port_info=b.ifindex_info and lg_id in (' ||
 
lg_id ||
 
') and a.device_id = b.device_id ) and a.collecttime >=' ||
 
tmp_begin_time || ' and a.collecttime <=' ||
 
tmp_end_time || ' order by collecttime' ;
 
Dbms_Output.put_line(v_SQLStatement);
 
/*針對字符串sql打開遊標*/
 
open v_Cur for v_SQLStatement;
 
tmp_begin_time := tmp_begin_time + 300 ;
 
tmp_end_time := tmp_end_time + 300 ;
 
total_ifinoctetsbps := 0 ;
 
total_ifoutoctetsbps := 0 ;
 
loop
 
/*將遊標的值放入零食變量中*/
 
fetch v_Cur
 
into tmp_ifinoctetsbps, tmp_ifoutoctetsbps;
 
/*當遊標中不存在值時跳出遊標*/
 
EXIT WHEN v_Cur% NOTFOUND;
 


total_ifinoctetsbps := total_ifinoctetsbps + tmp_ifinoctetsbps; 
total_ifoutoctetsbps := total_ifoutoctetsbps + tmp_ifoutoctetsbps;
 
end loop ;
 
/*單行記錄初始化*/
 
v_Table := type_flux_data_stat_o(total_ifinoctetsbps,
 
total_ifoutoctetsbps,
 
tmp_begin_time);
 
/*將記錄壓入至結果集中*/
 
pipe row (v_Table);
 
/*關閉遊標*/
 
close v_Cur;
 
end loop ;
 
Exception
 
when others then
 
Dbms_Output.put_line( Sqlerrm );
 
end f_linkgroupstat;
 
使用方法爲table(方法)做爲表查詢方式,其間沒有臨時表,形如:
select * from table(f_linkgroupstat(1361980800,1362067200,'34','FLUX_DATA_2013_2_28')) a;
 
289 rows selected.
 
Elapsed: 00:00:00.28
   執行時間爲:28ms
相關文章
相關標籤/搜索