PDA

View Full Version : SQLRPGLE Get und Set Prozeduren



Seiten : [1] 2

iseries_user
11-05-16, 06:57
Guten Morgen zusammen,

In Java gibt es beim Zugriff auf Objekte Get und Set Methoden.
Wir wollen so etwas für unsere Dateien als Serviceprogramm einführen.

Man soll also einzelne Felder aus einer Datei mit Get_FELD1 auslesen können. Als Übergabe erhält die Prozedur den Eindeutigen Schlüssel. In der Prozedur Get_FELD1 wird dann ein entsprechender SQL ausgeführt und der Wert mit Return zurück gegeben.

Wie sieht es mit der Performance aus, wenn ich aus einer Datei hintereinander 3 Felder abgreife?
Also ein Get_FELD1 dann Get_FELD2 und Get_FELD3 aus einer Datei mit dem selben Schlüssel.
Muss dann jedesmal ein Zugriffspfad aufgebaut werden?

Es läuft in der selben Aktivierungsgruppe.


Danke für eure Hilfe
iseries_user

andreaspr@aon.at
11-05-16, 08:10
Der Zugriffspfad (ODP) bleibt nach dem 2. mal geöffnet.
Ab 7.1 gibt es sogar einen QAQQINI Eintrag mit dem angegeben werden kann, ab dem wievielten mal öffnen der ODP offen bleiben soll.

Du kannst es prüfen in dem du entweder
* den Debug Mode mit laufen lässt (STRDBG) und dann ins Joblog schaust. Dort steht dann drinnen ob der ODP neu erstellt oder wiederverwendet wurde
* oder du ein DB Monitor startest. Dort siehst du auch ob ein oder mehrere "hard open" gemacht werden.

lg Andreas

iseries_user
11-05-16, 08:12
Super.

Vielen Dank. Einfach schlau die AS/400 :)

BenderD
11-05-16, 08:25
... das ist natürlich weniger als die halbe Wahrheit. Das wäre sehr wohl Performance relevant und im wirklichen Leben macht man das so, wie Java das auch macht. Die getter und setter in Java beziehen sich immer auch Objekte, im Allgemeinen also nicht auf elementare Variablen. In Java wäre das dann ein Kunde, oder ein Auftrag. Im ersten Fall (Kunde) dann ein einzelner Datensatz, im zweiten Fall ein kompletter Auftrag, also sowohl der Kopfsatz, als auch alle Positionen und alle ausnormaliserten Daten hinzugezogen.
Performance gewinnt man in SQL durch mehr Grobkörnigkeit, also gerade nicht Zugriffe auf einzelne Columns, sondern denkein in Ergebnismengen, was dann die Anzahl der Datenzugriffe (fetch) gegenüber Leseoperationen im RLA drastisch verringert!

D*B

andreaspr@aon.at
11-05-16, 08:33
Nachtrag: die DB schließt den ODP automatisch von selbst wenn bestimmte Kriterien erfüllt werden.
Z.B. Wenn also ein ALTER TABLE abgesetzt wird, werden alle ODPs (die von SQL offen gehalten werden) automatisch geschlossen um die Sperren aufzuheben.

Fuerchau
11-05-16, 08:45
Die Performance auf diese Art mit einzelnen SQL's zu lösen ist wirklich grottenschlecht.
Ich habe das für einen Kunden realisiert (es wurde als SQL-Funktion benötigt) und musste hier dramatische Einbußen hinnehmen.
In Java ist es so, dass ich einen Datensatz lese und mit den entsprechenden GetSet-Methoden nur noch auf Speicherobjekte zugreife. Ein SQL wird da nicht mehr ausgeführt.
Möchtest du das dynamisch in einer ILE-Prozedur analog betreiben musst du den Datansatz per SQL komplett einlesen und dir eine Tabelle der Feldnamen mit den Werten dazu aufbauen (das geht auch dynamisch). Dann stellst du eine "READ"-Funktion zur Verfügung, die ggf. über den Schlüssel cached und einzelne Get/Set's für die Feldinformationen.
Um es mit dem Begriff "Streng typisierte Objekte" zu vergleichen müsstest du real für jedes Feld einen namentlichen Get/Set-Zugriff generieren, also GetKundenNr/SetKundenNr, GetName1/SetName1, ...
Da ILERPG aber nicht objektorientiert ist kann man solche Ansätze eher in die Tonne drücken da sie weder performant noch hilfreich sind.
Ein simpler Zugriffshandler für komplette Strukturen mit diversen Zugriffen ist da allemal effektiver und logischer.

dschroeder
11-05-16, 08:47
Eine Idee, um die möglicherweise suboptimale Performance zu verbessern, wäre es, wenn sich deine Procedure merkt, wie der Schlüssel beim letzten Aufruf war. Dann könntest du nur beim ersten Aufruf den gesamten Datensatz holen und in eine extern definierte Datenstruktur schreiben. Alle Folgeaufrufe mit gleichem Schlüssel würden dann kein eigenes SQL mehr ausführen, sondern einfach das Feld aus dem bereits geholten Datensatz zurückgeben.

Dieter

BenderD
11-05-16, 08:56
... nuir mal selber vergleichen:
Variante 1: sql Zugriff pro Feld
Variante 2: sql Zugriff pro Datensatz
Variante 3: Blockfetch in ArrayDS für kompletten Auftrag mit allen Joins!!!

natürlich kann eine Serviceprogramm dann das alles in calls auf getXYZ für jedes Feld auflösen, aber die Programmierer Performance wäre katastrophal - das will doch alles getippt werden!!!

D*B

Fuerchau
11-05-16, 09:12
Nun, vielleicht fällt da einem ein Generator für so einen Quatsch ein.
Zu bedenken ist ja noch folgendes:
Ein Serviceprogramm wird ja innerhalb des Jobs von verschiedenen Programmen aufgerufen.
Also nur simple Get/Set-Routinen reichen da nicht aus, da der "aktuelle" Datensatz inzwischen gewechselt sein könnte.
Wer es denn kompliziert mag, kann noch D*B's Hashtable-Implementation verwenden um je Programm per zusätzliche Id auf den jeweils gecachten Satz zuzugreifen.
Wer dabei allerdings noch den Überblick behalten will...

BenderD
11-05-16, 09:16
... dafür würde ich aber (m)einen echten cache nehmen, der ist aber (noch) nicht Open Source.