Manchmal wünscht man sich mit FreeMarker auf Variablen zugreifen zu können, die aus der Datenbank gefüllt werden müssten, weil sie nicht als Felder auf der Maske vorkommen. Allerdings muss die Freemarker-Transformation ja schon laufen, bevor der fertige SQL an die Datenbank geschickt wird, weil Postgres/Informix ja mit FreeMarker-Befehlen nichts anfangen können.
Man kann also nicht so etwas
<#assign gegename="select name from fin_geldgeber G where G.xyz=<>">
machen, weil die Variable gegename dann einfach nur select... als String enthält, Freemarker hat mit der Datenbank keinen direkten Kontakt.
Dies lässt sich umgehen, indem man einen Block anlegt:
<!-- einfache Variable--<!-- einfache Variable-->
select sp_table_exists('fin_geldgeber') from xdummy
<!-- Listenvariable -- 1. Spalte key (darf nicht null sein!), 2. Spalte name--<!-- Listenvariable -- 1. Spalte key (darf nicht null sein!), 2. Spalte name-->
select ggnr,ggname1 from fin_geldgeber
Anschließend kann man in der Abfrage mit FreeMarker auf diese aus der Datenbank gefüllten Variablen zugreifen:
<#if fin_geldgeber_exists=1<#if fin_geldgeber_exists=1> insert into .. select * from fin_geldgeber; <#else>
insert into .. select * from fin_geldgeber; #if>
Die Variable wird als einfacher Wert erkannt, weil nur eine Spalte im SQL selektiert wurde. Sofern der Select mehrere Zeilen liefert, wird nur der letzte gefundene Wert hinterlegt.
Die zweite Art von Variable (geldgeber) wird als Liste von Items geführt und kann in der Abfrage benutzt werden z.B. mit
where ggnr in ( <#foreach gg in geldgeber<#foreach gg in geldgeber> ${gg.key}, #foreach>
Die erste per SQL eingelesene Spalte ist das Attribut key, die zweite name.
Optional kann auch noch dritte/vierte Spalte mit Strukturinfo eingelesen werden:
select ggnr,ggname1,klr_geldgeber,strukturint from fin_geldgeber
Auf die dritte Spalte kann man zugreifen über das Attribut ".strukturStr", und die vierte Spalte mit ".strukturInt", also für das orbige Beispiel mit:
<#foreach gg in geldgeber <#foreach gg in geldgeber > -- Hier steht der Inhalt der Spalte klr_geldgeber: ${gg.strukturStr} ...
Analog für strukturInt.
In den sqlvars kann auch freemarker-syntax und repository/konstanten benutzt werden, obstruses Beispiel:
<#if K_FIN_Quellsystem=1<#if K_FIN_Quellsystem=1> select ggnr,ggname1 from fin_geldgeber where ggnr in ${FIN_Drittmittel} <#else>
select ggnr,ggname2 from fin_geldgeber where ggnr in ${FIN_Drittmittel} #if>
Achtung : bei den SQL-Statements innerhalb von SQLVAR-Abschnitten dürfen Sie keine "<" oder ">"-Zeichen nutzen, sondern mit der html-Notation < und > umschreiben, also statt:
select distinct tid, eintrag from semester where tid < =20101 order by 1;
schreiben Sie besser
select distinct tid, eintrag from semester where tid < =20101 order by 1;
Bei Problemen mit sqlvars, deren SQL dynamisch generiert werden, ist es schwierig, sich den produzierten SQL anzusehen (insb. wenn nur Browserzugriff besteht).
Beispiel:
<!sum(hhans)">from fin_konto_aggr where rechnungsjahr= < >
and ch110_institut in ${Kostenstelle.allNeededElements}>
Trick: Einen SQL-Syntaxfehler einbauen:
<!XXXXX">sum(hhans) from fin_konto_aggr where rechnungsjahr= < >
and ch110_institut in ${Kostenstelle.allNeededElements}>
Dadurch wird ein SQL-Fehler erzeugt, der im Browser angezeigt wird und man kann sehen, wie <
Man kann auch Inhalt von Freemarker-Variablen bzw. vorhergehenden SQLVars anzeigen lassen.
Beispiel Konstante FIN_Quellsystem und vorhergehende sqlvar instname:
select drucktext from fin_inst where key_apnr=<>
<!'${K_FIN_Quellsystem}">- ${instname}' from xdummy; select XX sum(hhans) from fin_konto_aggr where rechnungsjahr= < >
and ch110_institut in ${Kostenstelle.allNeededElements}>
In sqlvars kann man auch auf die vorherigen sqlvars zugreifen:
select ..
<!.. where <#if">v1=1<#if v1=1> feld=1 <#else>
feld=2 #if>>
geht bisher nur innerhalb von if-Anweisungen o.ä.
CDATA ist wichtig für wohlgeformtes xml
select apnr from konstanten where beschreibung=' COB_FIN_STARTJAHR '
<!distinct">klrjahr*12+klrmonat,'monat' from fin_buch_akt where klrjahr>0 and klrjahr>=${COB_FIN_TO_BUSA_STARTJAHR}>
hier kommt Fehlermeldung smallint Operator >= existiert nicht.
Hintergrund:
${COB_FIN_TO_BUSA_STARTJAHR} wird als $-Kommentar vom klassischen general-sql gelöscht und
select distinct klrjahr*12+klrmonat,'monat' from fin_buch_akt where klrjahr>0 and klrjahr>=
abgeschickt.