Abfragen mit variabler Spaltenzahl

Es ist nun mit FreeMarker auch möglich, Abfragen mit einer variablen Anzahl von Ergebnisspalten zu erzeugen. Dazu muss mit Freemarker an zwei Stellen Variabilität eingebracht werden:

- im SQL der Maske und

- in der XIL-Proplist, die die Definition der Ergebnisspalten enthält.

Einfaches Beispiel:

Im FIN-Modul gibt es zwei Quellsysteme (MBS und KAHIKA). Je nach Quellsystem soll in einer Abfrage unterschiedliche Spalten erscheinen. Das Quellsystem kann über die Konstante FIN_QUELLSYSTEM ermittelt werden (Zugriff über FreeMarker als K_FIN_QUELLSYSTEM, 1=MBS, 2=KAHIKA). Am Ende des Masken-SQLs kann beispielweise stehen:

 

<#if K_FIN_Quellsystem=2>

select eintrag, hhans,reste, bewegungen, fest, verfuegbar, verfuegbar-fest from tmp_erg order by dr,sortnr,tit;

<#else>

select eintrag, hhans,reste,akts_ein, sperr, angeordneta,offsoll_a,angeordnete,offsoll_e, fest, verfuegbar, verfuegbar-fest from tmp_erg order by dr,sortnr,tit;

</#if>

.

Die definierten Spaltenüberschriften in der XIL-Proplist müssen ebenfalls variabel angelegt werden:

--freemarker template

XIL List

   drop_and_delete movable_columns sizable_columns horizontal_scrolling

   white_space_color=COLOR_WHITE fixed_columns=1

   min_heading_height=35

Column CID=0 heading_text="Titel / DR" center_heading

   row_selectable col_selectable heading_platform readonly

   width=20 text_size=8 explanation="@@@fin_titel_dr@@@"

Column CID=0 heading_text="Zuweisungen" center_heading

   row_selectable col_selectable heading_platform readonly

   width=15 text_size=8 explanation="@@@fin_zuweisungen@@@"

Column CID=0 heading_text="Reste" center_heading

   row_selectable col_selectable heading_platform readonly

   width=15 text_size=8 explanation="@@@fin_reste@@@"

<#if K_FIN_Quellsystem=2>

   Column CID=0 heading_text="Bewegungen" center_heading

   row_selectable col_selectable heading_platform readonly

   width=15 text_size=80 explanation="@@@fin_bewegungen@@@"

<#else>  

Column CID=0 heading_text="Akt.Soll" center_heading

   row_selectable col_selectable heading_platform readonly

   width=15 text_size=8 explanation="@@@fin_akt_soll@@@"

   ...

</#if>

   Column CID=1 heading_text="Festgelegt" center_heading

   row_selectable col_selectable heading_platform readonly

   width=15 text_size=80 explanation="@@@fin_festgelegt@@@"

 

Grundprinzip ist also, dass mit FreeMarker die Variablität in den SQL und die XIL-Proplist gebracht werden muss.

 

Ein komplexes Beispiel:

In einer Abfrage soll ein variable Anzahl von Lehreinheiten in den Spalten erscheinen, diese können nicht direkt aus einem Sicht-Feld Lehreinheiten ermittelt werden (in FreeMarker wäre dann z.B. Zugriff über <#foreach lehrein in Lehreinheiten> möglich). Stattdessen wird die Gesamtliste aller gewünschten Lehreinheiten über die Felder Semester und Anbietende Lehreinheit definiert. Damit Freemarker vor der eigentlichen Transformation noch eine passende aus der Datenbank gefüllt Variable erhält, wird am Anfang der Abfrage eine sqlvar namens lehr_abg angelegt (vergl. Abschnitt zu Variabeln).

 

--Freemarker Template

<#include "SQL_lingua_franca"/>

<#include "SuperX_general"/>

<sqlvars>

<sqlvar name="lehr_abg">

SELECT distinct L.key_apnr,

       L.drucktext, L.name as strukturstr

 from gang_k_lehr_hs L, gang_k_semester S

  where

1=1

/* and L.key_apnr in(<<Anbietende Lehreinh.>>) */

/* and S.tid = <<Semester>> */

 and S.sem_beginn between L.gueltig_seit and L.gueltig_bis

order by 2;

</sqlvar>

</sqlvars>

Anschließend wird die Ergebnistabelle variabel erzeugt (has_content prüft, ob überhaupt Lehreinheiten gefunden wurden).

create temp table tmp_gang_cnw2 (

ord integer,

tid integer,

semester_von integer,

sem_beginn date,

lehr_abg character(10),

lehr_empf character(10),

lehr_empf_str char(255),

lehr_empf_sort char(255),

stg_empf_str nchar(255)

<#assign i=0 />

<#if lehr_abg?has_content >

<#foreach row_gang in lehr_abg>

<#assign i=i+1 />

, lehr_${i} decimal(5,2)

</#foreach>

</#if>

)

 

An späterer Stelle können variabel updates auf die Ergebnistabelle gemacht werden, damit kann mit .key auf den Schlüssel der Lehreinheit zugegriffen werden.

 

<#assign i=0 />

<#if lehr_abg?has_content >

<#foreach row_gang in lehr_abg>

<#assign i=i+1 />

update tmp_gang_cnw2 set lehr_${i} = (select sum( C.ca_wert)

from tmp_gang_cnw C

where C.lehr_abg=tmp_gang_cnw2.lehr_abg

and C.lehr_empf=tmp_gang_cnw2.lehr_empf

and C.tid=tmp_gang_cnw2.tid

and tmp_gang_cnw2.lehr_abg='${row_gang.key}')

where ord=2;

</#foreach>

</#if>

 

Zum Schluss könnte man einfach select *  from tmp_xx; machen, oder sicherheitshalber besser:

 

select ord as ebene, stg_empf_str

<#assign i=0 />

<#if lehr_abg?has_content >

<#foreach row_gang in lehr_abg>

<#assign i=i+1 />

, lehr_${i}

</#foreach>

</#if>

 from tmp_gang_cnw4

 

Schließlich muss nur noch die XIL-Proplist variabel erzeugt werden, dabei kann mit .name auf den Namen der Lehreinheit zugegriffen werden.

 

XIL List

   sizable_columns horizontal_scrolling

   white_space_color=COLOR_WHITE fixed_columns=1

   min_heading_height=35

Column CID=0 heading_text="Ebene" explanation="" center_heading

   row_selectable col_selectable rightJust heading_platform readonly

   width=30

Column CID=1 heading_text="NachfragendenLehreinheit\\nStudiengang" explanation="" center_heading

   row_selectable col_selectable rightJust heading_platform readonly

   width=30

<#assign i=1 />

<#if lehr_abg?has_content >

<#foreach row_gang in lehr_abg>

<#assign i=i+1 />

Column CID=${i} heading_text="${row_gang.name}" explanation="" center_heading

   row_selectable col_selectable rightJust heading_platform readonly

   width=20

</#foreach>

</#if>

 

Die volle Flexibilität ist im XML-Frontend gegeben. Da sich das Applet Spaltendefinitionen merkt, kann es Unstimmigkeiten geben, wenn die Spaltenzahl von Auswahlfeldern der Maske abhängt.


Zur Superx-Homepage SuperX ist auch ein CampusSource-Projekt. Zur CampusSource-Homepage | Powered by FreeMarker Seite 40 / 102
Letzter Update: 17.06.2008
Impressum