Sorry for the delay,
small example: I have 6 tables with pre-grouped page impressions for the WebServer logfiles, containing parameters to identify which content is most interesting for our users.
Our CEOs and partners can select the lookup-parameters on a web page and get result sets grouped to get a peak-analysis or a topic-analysis.
I build up the
col_stm (select column clause)
frm_stm (from clause)
whr_stm (where clause)
grp_stm (group_by clause)
then I concat these in the correct order to form the query (qry_stm) and then I use dynamic SQL to get the record-set into a CURSOR VARIABLE returning it from the database to the application. (By this way only the final result is sent to the web-server reducing network traffic and page build up speed, also the database is much quicker with grouping algorithms than an application). Of course you will have to define your cursor variable first!
CREATE OR REPLACE PACKAGE pk_cursor
AS
TYPE allgCursor IS REF CURSOR;
END pk_cursor;
/
CREATE OR REPLACE PROCEDURE stat_report (
c_table IN OUT pk_cursor.allgCursor
,p_ArtAuswahl IN VARCHAR2
,p_ZeitWahl IN VARCHAR2
,p_Datum IN VARCHAR2 := NULL
,p_Vergleich IN VARCHAR2 := NULL
,p_Mandant IN VARCHAR2 := NULL
,p_Rubrik IN VARCHAR2 := NULL
,p_Thema IN VARCHAR2 := NULL
,r_Message OUT VARCHAR2
)
AS
-- r_Message VARCHAR2(200);
v_ArtText VARCHAR2(25);
qry_stm VARCHAR2(1000);
col_stm VARCHAR2(100);
grp_stm VARCHAR2(100);
whr_stm VARCHAR2(300);
frm_stm VARCHAR2(100);
BEGIN
IF (p_ArtAuswahl = '0') THEN
-- First set the text for the PI-headline
v_ArtText := 'zeitlichen Verlauf';
-- Now generate the selected column-/group- and from-definitions
IF (RTRIM(p_Zeitwahl) = 'Wochen') THEN
col_stm := ' SELECT pi_week||pi_year PI_TIME, sum(pi_counts) PI_COUNTS';
grp_stm := ' GROUP BY pi_year, pi_week ';
frm_stm := ' FROM pi_per_weak ';
ELSE
col_stm := ' SELECT pi_time PI_TIME, sum(pi_counts) PI_COUNTS';
grp_stm := ' GROUP BY pi_time ';
IF (RTRIM(p_Zeitwahl) = 'Monate') THEN
frm_stm := ' FROM pi_per_month ';
ELSIF (RTRIM(p_Zeitwahl) = 'Tage') THEN
frm_stm := ' FROM pi_per_day ';
ELSIF (RTRIM(p_Zeitwahl) = 'Stunden') THEN
frm_stm := ' FROM pi_per_hour ';
ELSE
r_Message := 'kein gültiger Zeitraum für zeitlichen Verlauf! ';
RETURN;
END IF;
END IF;
-- add the mandant-definition to the where clause
IF (p_Mandant IS NULL OR p_Mandant = '0') THEN
whr_stm := '';
ELSE
whr_stm := 'WHERE client = '|| p_Mandant;
END IF;
IF (p_Rubrik IS NULL OR p_Rubrik = '') THEN
whr_stm := whr_stm || '';
ELSE
IF (INSTR(whr_stm,'WHERE',1) > 0 ) THEN
whr_stm := whr_stm || ' AND rubrik = ''' || p_Rubrik || '''';
ELSE
whr_stm := ' WHERE rubrik = ''' || p_Rubrik || '''';
END IF;
END IF;
IF (p_Thema IS NULL OR p_Thema = '') THEN
whr_stm := whr_stm || '';
ELSE
IF (p_Rubrik = 'Urlaub/Freizeit') THEN
whr_stm := ' AND uf_category = ''' || p_Thema || '''';
ELSIF (p_Rubrik = 'Handel/Wirtschaft') THEN
whr_stm := ' AND uv_category = ''' || p_Thema || '''';
ELSIF (p_Rubrik = 'Veranstaltungen') THEN
whr_stm := ' AND eventcategory = ' || p_Thema;
ELSIF (p_Rubrik = 'Lebenslagen') THEN
whr_stm := ' AND ls_category = ' || p_Thema;
ELSIF (p_Rubrik = 'Behörden') THEN
whr_stm := ' AND auth_category = ' || p_Thema;
ELSIF (p_Rubrik = 'Nachrichten') THEN
whr_stm := ' AND newscategory = ' || p_Thema;
END IF;
END IF;
qry_stm := col_stm || frm_stm || whr_stm || grp_stm;
OPEN c_table FOR qry_stm;
ELSIF (p_ArtAuswahl = '1') THEN
-- First set the text for the PI-headline
v_ArtText := 'inhaltlichen Vergleich';
-- Now generate the selected column-/group- and from-definitions
IF (RTRIM(p_Zeitwahl) = 'Wochen') THEN
frm_stm := ' FROM pi_per_weak ';
whr_stm := ' WHERE pi_week = ' || SUBSTR(p_Datum,1,INSTR(p_datum,',',1)-1) ||
' AND pi_year = ' || SUBSTR(p_Datum,INSTR(p_datum,',',1)+1,4);
ELSE
IF (RTRIM(p_Zeitwahl) = 'Jahr') THEN
frm_stm := ' FROM pi_per_month ';
whr_stm := ' WHERE TO_CHAR(pi_time,''yyyy'') = ''' || p_Datum || '''';
ELSIF (RTRIM(p_Zeitwahl) = 'Monate') THEN
frm_stm := ' FROM pi_per_month ';
whr_stm := ' WHERE TO_CHAR(pi_time,''mm.yyyy'') = ''' || p_Datum || '''';
ELSIF (RTRIM(p_Zeitwahl) = 'Tage') THEN
frm_stm := ' FROM pi_per_day ';
whr_stm := ' WHERE TO_CHAR(pi_time,''dd.mm.yyyy'') = ''' || p_Datum || '''';
ELSE
r_Message := 'kein gültiger Zeitraum für einen Vergleich! ';
RETURN;
END IF;
END IF;
IF (p_Vergleich IS NULL) THEN
r_Message := 'keine inhaltliche Größe für den Vergleich definiert! ';
RETURN;
ELSIF (p_Vergleich = 'Mandant') THEN
frm_stm := frm_stm || 'a, vmb_mandant b';
whr_stm := whr_stm || ' AND a.client = b.mand_id ';
col_stm := ' SELECT b.mand_name PI_VGL, sum(a.pi_counts) PI_COUNTS';
grp_stm := ' GROUP BY b.mand_name ';
qry_stm := col_stm || frm_stm || whr_stm || grp_stm;
OPEN c_table FOR qry_stm;
ELSIF (p_Vergleich = 'Referrer') THEN
grp_stm := ' GROUP BY referrer ';
frm_stm := 'FROM (SELECT referrer, sum(pi_counts) AS pi_counts ' ||
' FROM pi_per_referrer ' || whr_stm || grp_stm || ') ';
whr_stm := ' WHERE rownum < 21 ';
col_stm := ' SELECT referrer PI_VGL, pi_counts PI_COUNTS';
qry_stm := col_stm || frm_stm || whr_stm ;
OPEN c_table FOR qry_stm;
ELSIF (p_Vergleich = 'Domain') THEN
grp_stm := ' GROUP BY domain ';
frm_stm := 'FROM (SELECT domain, sum(pi_counts) AS pi_counts ' ||
' FROM pi_per_domain ' || whr_stm || grp_stm || ') ';
whr_stm := ' WHERE rownum < 21 ';
col_stm := ' SELECT domain PI_VGL, pi_counts PI_COUNTS';
qry_stm := col_stm || frm_stm || whr_stm ;
OPEN c_table FOR qry_stm;
ELSIF (p_Vergleich = 'Rubrik') THEN
IF (p_Mandant = '0' OR p_Mandant IS NULL) THEN
whr_stm := whr_stm;
ELSE
whr_stm := whr_stm || ' AND client = ' || p_Mandant;
END IF;
col_stm := ' SELECT rubrik PI_VGL, sum(a.pi_counts) PI_COUNTS';
grp_stm := ' GROUP BY rubrik ';
qry_stm := col_stm || frm_stm || whr_stm || grp_stm;
OPEN c_table FOR qry_stm;
END IF;
ELSE
r_Message := 'keine gültige Statistik-Art gewählt! ';
RETURN;
END IF;
r_Message := 'Die Abfrage ergibt einen ' ||
v_ArtText || ' über ' ||
p_Zeitwahl || ' ' || p_Datum || ' für ' ||
p_Mandant || ', ' || p_Rubrik || ', ' ||
p_Thema ;
EXCEPTION
WHEN OTHERS
THEN
r_Message := 'Die gewählten Parameter ergeben keine gültige Auswahl';
END stat_report;
/