Application Express und die SQL Model Clause

Werbung
Entwicklung
Application Express und die SQL Model
Clause – Tabellenkalkulation wie mit Excel
Carsten Czarski, ORACLE Deutschland GmbH
Bereits mit Oracle10g wurde die SQL Model Clause eingeführt – sie macht es möglich, im Ergebnis einer SQL-Abfrage so
mit Formeln zu rechnen, wie man es von einem Tabellenkalkulationsprogramm wie Excel gewohnt ist. Dieser Artikel
beschreibt, wie man die SQL Model Clause in einer Application-Express-Anwendung nutzt – und somit in einem Application-Express-Bericht – wie in Excel rechnen kann. Grundlage ist ein HowTo-Dokument aus der deutschsprachigen Seite der
Application-Express-Community.
Ausgangspunkt für das Anwenden der
SQL Model Clause ist ein einfacher
APEX-Bericht auf die bekannte Tabelle
EMP. Grundlage ist die einfache SQLAbfrage select * from emp.
Die SQL Model Clause betrachtet die Ergebnismenge einer Abfrage
wie ein Arbeitsblatt einer Tabellenkalkulation. Nach dem Schlüsselwort
model werden die Dimensionen (dimensions) und die Werte (measures)
deklariert. Die Dimensionen dienen
zum Ansprechen der Werte, die selbst
durch die nachfolgenden Rules verändert werden können. Im Folgenden ist
nun beschrieben, wie ein ApplicationExpress-Bericht so erweitert werden
kann, dass der Endbenutzer Formeln
eingeben kann, die der Bericht automatisch auswertet.
Schritt 1 – APEX-Bericht für SQL
Model-Clause vorbereiten
Man fügt der APEX-Anwendung mit
dem Bericht ein Formular-Eingabefeld
(Textbereich) zur Eingabe der Formeln
(PX_RULES) und eine Schaltfläche zum
Absenden derselben hinzu. Die APEXSeite soll nach Berechnung auf sich
selbst verzweigen.
Die eingegebenen Formeln müssen
in die SQL-Abfrage „integriert“ werden;
daher wird für den Bericht nun ein PL/
SQL-Block, der ein SQL-Kommando zurückgibt als „Quelle“ hinterlegt. Damit
das Ergebnis etwas mehr nach einem
Spreadsheet aussieht, werden die Spalten
mit A,B,C,D,E benannt. Zusätzlich soll
die Spalte F als leere numerische Spalte
(SQL NULL) angelegt werden. Der Quell-
declare
v_sql varchar2(32767);
begin
v_sql := ‚select zeile, a, b, c, d, e, f‘;
v_sql := v_sql || ‚ from emp ‚;
v_sql := v_sql || ‚ model ‚;
v_sql := v_sql || ‚ dimension by (rownum zeile) ‚;
v_sql := v_sql || ‚ measures ( ‚;
v_sql := v_sql || ‚
empno a, ename b, hiredate c, ‚;
v_sql := v_sql || ‚
sal d, comm e, cast(null as number) f ‚;
v_sql := v_sql || ‚ ) ‚;
v_sql := v_sql || ‚ rules upsert (‚;
v_sql := v_sql ||
:PX_RULES;
v_sql := v_sql || ‚)‘;
v_sql := v_sql || ‚order by zeile‘;
return v_sql;
end;
Listing 1: PL/SQL-Quellcode für den APEX-Bericht
code für die Berichtsregion sieht demnach wie folgt aus: (siehe Listing 1):
Der PL/SQL-Code setzt eine SQL-Abfrage zusammen und verwendet dabei die
SQL Model Clause – der Aufbau ist wie
folgt:
•
Die einzelnen Werte im virtuellen
Spreadsheet werden über die DIMENSION angesprochen. Die EMPTabelle hat nur eine Dimension, die
EMPNO; über diese werden alle Zeilen identifiziert. Hier wählen wir jedoch die ROWNUM, also die Zeilennummer des Berichts. Im Gegensatz
zu einem Spreadsheet in Excel können für die SQL Model Clause auch
mehr als zwei Dimensionen verwendet werden.
•
Die MEASURES sind die betroffenen
Werte; vergleichbar mit den Zelleninhalten eines Excel-Spreadsheets.
Bis auf die Zeilennummer sollen alle
Werte mit Formeln verändert werden können.
•
Danach folgen die RULES, die Formeln. Das Schlüsselwort UPSERT
bewirkt, dass die Formeln sowohl
bestehende Zeilen im Ergebnis ändern als auch neue Zeilen hinzufügen können. All dies betrifft nur die
Ergebnismenge des Berichts – nicht
die eigentliche Tabelle.
Die Application-Express-Anwendung
sieht nun in etwa wie in Abbildung 1
aus:
DOAG News Q4-2008 | 37
Entwicklung
f[1] = (d[1] / d[2] - 1) * 100
Wie hoch ist der Durchschnitt aller
Gehälter? d[15] = avg(d)[ANY]
Abbildung 1: Die Daten der Tabelle EMP als normaler Application-Express-Bericht
Eine Zelle wird immer mit ihrem Namen angesprochen – hier A bis F. Die
Navigation entlang der Dimensionen
(hier die Zeilennummer) erfolgt mithilfe der eckigen Klammern. In diesem Beispiel enthalten die eckigen
Klammern nur einen Wert, da in der
Model Clause nur eine Dimension bestimmt wurde. Das Schlüsselwort ANY
in der letzten Formel bedeutet dabei
„alle“; d[ANY] meint also: „alle Zellen
der Spalte D“. Das Ergebnis sollte wie
in Abbildung 2 aussehen.
Gerade, wenn es darum geht, Daten
für Endbenutzer aufzubereiten, kann
die SQL Model Clause ein wertvolles
Hilfsmittel sein. Wichtige Berechnungen, die im ganzen Unternehmen einheitlich erfolgen sollen, lassen sich
hier als RULES hinterlegen.
Eine Anwendung der SQL Model Clause:
Finanzmathematik
Ein Beispiel aus dem Finanzbereich demonstriert noch einige weitere wichtige Merkmale der SQL Model Clause.
Es soll ein Annuitäten-Darlehen berechnet werden. Bei dieser Form des
Darlehens wird monatlich eine feste
Rate gezahlt; insofern sinkt der Zinsanteil jeden Monat, wohingegen der
Tilgungsanteil entsprechend steigt.
Schritt 1 – APEX-Bericht für SQL
Model Clause vorbereiten
Abbildung 2: Application-Express-Bericht mit SQL Model Clause
Schritt 2 – SQL Model Clause
in Aktion: Erste Tests
•
Man gibt nun, durch Komma getrennt,
ein paar Formeln ein. Das Prinzip ist
immer dasselbe:
•
38 | www.doag.org
Man ändert in der zweiten Zeile den
Namen von BLAKE in SCHMIDT:
b[2] = ‚SCHMIDT‘
Man berechnet, um wie viel Prozent das Gehalt von KING über dem
von BLAKE (jetzt SCHMIDT) liegt
Man legt eine neue Seite in der Application-Express-Applikation an. Sie
enthält wiederum das Element PX_
RULES zur Eingabe der Regeln und
einen Bericht, der (im Augenblick)
lediglich eine leere Zeile erzeugt, in
dem er sechs mal die Null (0) von der
Tabelle DUAL selektiert. Der PL/SQLBlock, der als Regionsquelle für den
APEX-Bericht hinterlegt wird, ist in
Listing 2 enthalten.
Die Model Clause bekommt noch
zwei zusätzliche Parameter. Schließlich
muss der Tilgungsplan für das Darlehen solange berechnet werden, bis
der Darlehensbetrag auf Null getilgt
Entwicklung
declare
v_sql varchar2(32767);
begin
v_sql := ‚select zeile, a, b, c, d, e, f‘;
v_sql := v_sql || ‚ from dual ‚;
v_sql := v_sql || ‚ model ‚;
v_sql := v_sql || ‚ dimension by (rownum zeile) ‚;
v_sql := v_sql || ‚ measures (0 a, 0 b, 0 c, 0 d, 0 e, 0 f) ‚;
v_sql := v_sql || ‚ rules upsert iterate (‚;
v_sql := v_sql ||
nvl(:PX_ITCOUNT,1);
v_sql := v_sql ||
‚) until (‚||nvl(:PX_ITUNTIL, ‚0=1‘);
v_sql := v_sql || ‚ ) ‚;
v_sql := v_sql || ‚(‚;
v_sql := v_sql || :PX_RULES;
v_sql := v_sql || ‚)‘;
v_sql := v_sql || ‚order by zeile‘;
return v_sql;
end;
Schritt 2 – SQL Model Clause
in Aktion: Tilgungsplan berechnen
Als Ergebnis liefert der Bericht vorerst
nur eine Zeile mit Nullen zurück. Im
Tilgungsplan sei A die Darlehenssumme, B die Zinsen, C die Tilgung und D
die jeweilige Rate. Es wird monatlich
getilgt. Zur Berechnung gibt man folgende Formeln ein:
1.a[0]=200000,
2.b[ITERATION_
NUMBER]=a[cv(zeile)]*0.06/12,
3.d[ITERATION_NUMBER]=2000,
4.c[ITERATION_NUMBER]=
d[cv(zeile)]-b[cv(zeile)],
5.a[ITERATION_NUMBER+1]=
a[cv(zeile)-1] - c[cv(zeile)-1]
Listing 2: PL/SQL-Quellcode für den APEX-Bericht zum Berechnen eines Tilgungsplans
wurde. Dazu dient das Schlüsselwort
ITERATE. Es nimmt eine Zahl und
zusätzlich optional eine Bedingung
entgegen; hier durch die Elemente PX_ITCOUNT und PX_ITUNTIL
repräsentiert. Man erzeugt diese beiden
Elemente also auf der APEX-Seite zusätzlich als normale Eingabefelder mit
den Labels Iterate für PX_ITCOUNT
und Bedingung für PX_ITUNTIL.
Abbildung 3: SQL Model Clause in Aktion
Die Regeln werden nun maximal
PX_ITCOUNT mal durchgearbeitet.
Wenn vorher die Bedingung PX_ITUNTIL erfüllt wird, bricht die Bearbeitung
ab. Die NVL-Funktionen dienen der
Hinterlegung von Default-Werten für
den Fall, dass die Elemente leer sind.
In diesem Fall soll genau eine Iteration
stattfinden und die Bedingung soll 1=0
(also stets false) sein. Abbildung 3 zeigt
die fertig vorbereitete Seite.
Wichtig bei den Formeln sind das
Schlüsselwort ITERATION_NUMBER
und die Funktion cv(). ITERATION_
NUMBER gibt die laufende Nummer der
aktuellen Iteration zurück, beginnend
mit 0. Während der ersten Iteration
steht ITERATION_NUMBER also für 0
(Null), in der zweiten für 1 und so fort.
cv() kann nur auf der rechten Seite der
Gleichung verwendet werden. Diese
Funktion gibt einfach nur die aktuelle Zeilennummer der Zelle zurück,
die auf der linken Seite angesprochen
wurde. cv() verwendet man also stets
dann, wenn man dieselbe Berechnung
in vielen Zeilen immer wieder durchführen möchten. Damit erklären sich
die Formeln wie folgt:
6. Die anfängliche Darlehenssumme
(A) beträgt 200.000
7. Der Zinssatz ist sechs Prozent; die Zinsen werden für einen Monat berechnet. Die Zinsen (B) in der jeweiligen
Zeile seien gleich dem Darlehensbetrag (A) in der gleichen Zeile multipliziert mit dem 0.06 geteilt durch 12.
Die Rate (D) sei in jeder Zeile gleich
2.000
8. Die Tilgung (C) sei in jeder Zeile
gleich der Rate (D) weniger die Zinsen (B) (in der gleichen Zeile)
9. Der Darlehensbetrag (A) in der
nächsten Zeile (ITERATION_NUMBER+1) sei gleich dem Darlehensbetrag (A) weniger der Tilgung (C) in
der letzten Zeile (cv(zeile) -1).
DOAG News Q4-2008 | 39
Entwicklung
Man gibt die Formeln ein, trägt zunächst ins Feld Iterate eine 100 ein und
betätigt die Schaltfläche. Das Ergebnis
sollte wie in Abbildung 4 aussehen.
Man erhöht die Iterationen (Formularfeld Iterate) noch weiter und blättert
im Bericht solange vor, bis man den
Bereich findet, in dem der Restbetrag
des Darlehens negativ wird. Ziel wäre
es nun, den Bericht hier abbrechen zu
lassen.
Dies geschieht mit der Bedingung
a[ITERATION_NUMBER]<=0; es soll
also so lange gerechnet werden, bis der
Darlehensbetrag auf Null oder darunter sinkt. Dann würde der Tilgungsplan in den meisten Fällen jedoch immer noch mit einem negativen Betrag
enden. Da das Darlehen exakt auf Null
getilgt werden soll, muss die letzte Rate
kleiner als 2000 sein. Die Formel für
die Rate
Abbildung 4: Vorbereitete Seite für den Tilgungsplan
3. d[ITERATION_NUMBER]=2000
wird also geändert in:
3. d[ITERATION_
NUMBER]=least(2000,
a[cv(zeile)]+b[cv(zeile)]),
Die SQL-Funktion LEAST nimmt zwei
oder mehr Ausdrücke entgegen und
gibt den kleinsten zurück. Wenn der
Restbetrag des Darlehens plus Zinsen
also weniger als 2000 ausmacht, wird
die Rate entsprechend reduziert.
Mit dieser Technologie kann man
also beliebige Kalkulationen (nicht
nur) in APEX-Anwendungen aufnehmen. Dabei wird, wie im ersten Beispiel, auf der Basis von Tabellendaten
gerechnet oder, wie im zweiten Beispiel, eine freie Kalkulation durchgeführt. Natürlich wird man den Endanwender in den seltensten Fällen die
Formeln eintippen lassen – dies erfolgte hier vor allem zum Zweck der
Illustration. Von hier ausgehend ist
es jedoch ein Leichtes, Eingabefelder
für die Darlehenssumme, den Zinssatz
und die Rate zu hinterlegen sowie die
Eingaben entsprechend in den Bericht
einzubauen.
Weitere Informationen
Auf den Web-Seiten von Oracle und
im Internet ist umfangreiches Material
auch in deutscher Sprache vorhanden
– hier ein Überblick:
•
•
Oracle Application Express Community
http://www.oracle.com/global/de/community/index.html
Oracle Dokumentation: SQL Model
Clause
http://download.oracle.com/docs/cd/
B28359_01/server.111/b28313/sqlmodel.htm#g1042989
Kontakt:
Carsten Czarski
[email protected]
DOAG intern
Die DOAG ist Ausbildungsbetrieb
Bereits seit 1. September 2008 bildet die DOAG im Beruf „Kaufmann/Kauffrau für Marketingkommunikation“ aus. Die erste Auszubildende ist Julia Kasprzak, die sich in einem aufwendigen Auswahlprozess
aus mehreren Dutzend Bewerbern erfolgreich durchgesetzt hat. Von der Ausbildung bei der DOAG
erwartet sie kreative Anstöße, die ihr einen beruflichen Weg über die Ausbildung hinaus aufzeigen,
und viel praktische Erfahrung, die sie auf diesem Weg weiterbringt. In ihrer Freizeit liest sie viel, geht
gerne auf gesellschaftlich/kulturelle Veranstaltungen (Theater, Musical, Ballett, Kino etc.) und wie die
meisten Menschen sucht sie im Urlaub gern die Sonne. Wir wünschen Julia Kasprzak viel Erfolg in der
Ausbildung bei der DOAG!
40 | www.doag.org
Herunterladen