PDA

View Full Version : VARPG und dynamisches SQL



Seiten : [1] 2

caltmann
09-12-08, 14:02
Hallo zusammen!

Wir sind gerade am Ausloten der SQL-Möglichkeiten mit VARPG,
stoßen dabei aber leider an gewisse Grenzen.
Ein konkretes Problem stellt das "FETCH" bei Verwendung von
Cursor-Zugriffen dar.
Die Angabe der HOST-Variablen muss ja in etwa so erfolgen:
"FETCH MyCsr INTO :KUNDE", wobei "KUNDE" den zurückgelieferten
Datentypen entsprechen muss (Feld oder Datenstruktur).
Unser Problem ist, dass erst zur Laufzeit feststeht, welche
Daten zurückgeliefert werden sollen. D.h. wir müssten
das "FETCH"-Statement ebenfalls dynamisch aufbauen.
Gibt es hier seitens VARPG irgendeine Möglichkeit,
dies zu bewerkstelligen?
Ev. durch Einsatz anderer DB-Anbindungen o.Ä?
Danke für Tipps
lg
Chris

Fuerchau
09-12-08, 14:12
Nunja, RPG und dynamisches SQL gestaltet sich halt schwierig.
Sinn und Zweck von embedded SQL ist ja eigentlich, dass das Programm genau die Daten liest, die es benötigt.

Für dynamische Cursor ist RPG (auch ILE und VARPG) weniger gut geeignet.

Hierfür sind SQLDA-Strukturen, SQL-Feldtypen und Pointer erforderlich und würde hier den Rahmen sprengen.

Ich würde mir da genauere Gedanken über die Funktion des Programmes machen.
Quasi-dynmaische Where-Klauseln sind da eher unproblematisch:

select ...
where key1 between : From1 and : To1 and ...

Wenn ein Selektionskriterium nicht gefüllt ist, füllt man halt FromX mit *loval und ToX mit *hival (o.ä.).

caltmann
10-12-08, 07:40
Der "Select" ist klar, das Problem sind bei uns ja
dann eher die Host-Variablen, die einmal numerisch
und das andere mal alphanumerisch sein können.
(...und jedes einzelne Feld abzufragen ist wohl performance-technisch uninteressant.)
OK, dann werden wir mal in die Richtung Pointer und dergl. weiterforschen...
Danke für den Hinweis.
Wir evaluieren auch die Möglichkeit z.B. ein C#-Programm
als Datengateway dazwischenzulegen, ich wollte aber das
mit VARPG Mögliche vorher zur Sicherheit abklären.

lg
Chris

Fuerchau
10-12-08, 08:04
So ganz verstehe ich das nicht.
Wenn ein Programm für eine bestimmte Aufgabe konzipiert ist, benötigt es keinen dynamischen SQL sondern verarbeitet genau die Daten, die es benötigt.

Gerade variable Feldtypen werden von RPG nicht unterstützt (andere Sprachen bieten den allgemeinen Typ Object/Variant).

Worin soll also die Variablilität bestehen ?

PS:
Selbst Pointer helfen in RPG nicht weiter, da du die Daten zwar lesen aber nicht tatsächlich verarbeiten kannst.

Um "variabel" zu arbeiten kannst du ggf. noch per "char(feld) as feld" alles in Alpha casten. Beim Select zwar unkritisch aber wie siehts dann beim Update/Insert aus ?

BenderD
10-12-08, 09:05
der Ansatz von embedded SQL ist es gerade den Prüfaufwand, soweit es geht in die Compiletime zu verlagern. Wenn man das nicht haben wil, benutzt man letztlich SQL Call level Interface und dafür ist die Unterstützung in RPG, egal welche Variante ungefähr gleich 0 (in Worten Null).

D*B


Der "Select" ist klar, das Problem sind bei uns ja
dann eher die Host-Variablen, die einmal numerisch
und das andere mal alphanumerisch sein können.
(...und jedes einzelne Feld abzufragen ist wohl performance-technisch uninteressant.)
OK, dann werden wir mal in die Richtung Pointer und dergl. weiterforschen...
Danke für den Hinweis.
Wir evaluieren auch die Möglichkeit z.B. ein C#-Programm
als Datengateway dazwischenzulegen, ich wollte aber das
mit VARPG Mögliche vorher zur Sicherheit abklären.

lg
Chris

caltmann
10-12-08, 09:15
Ok, die Variabilität, besteht darin, dass ein und dasselbe Programm aus unterschiedlichsten Tabellen die Felder
auslesen soll. D.h. nur ein "Leserprogramm" für sowohl Kundenstamm, als auch Auftragsdetails, als auch....
Der jeweils durch das vorbereitete dynamische Select
gefundene Satz soll dann, wenn man so will, als
großer String zurückgeliefert werden.
Um die Auswertung des Strings (von 1-6 Kundennummer, von 7-16 Kurzname,...) kümmern wir uns dann selbst.
Aber so wie ich eure Antworten verstanden habe, führt wohl kein Weg an einem externen Programm vorbei.
Danke euch!
lg
Chris

BenderD
10-12-08, 10:32
zumindest mich hast du hier völlig falsch verstanden, das halte ich nicht einmal für die zweitbeste Idee. Warum schmeißt ihr nicht gleich alle Daten auf einen großen sequentiellen Haufen, dann spart ihr euch doch viel Aufwand?!
Ergänzung: oder ihr setzt alle Files auf level check no und verwendet record level access mit internen Beschreibungen und einer ellen langen Dateibeschreibung, falls der Compiler Einwände hat, kriegt man das mit einem OVRDBF zur Laufzeit weg.

D*B


Ok, die Variabilität, besteht darin, dass ein und dasselbe Programm aus unterschiedlichsten Tabellen die Felder
auslesen soll. D.h. nur ein "Leserprogramm" für sowohl Kundenstamm, als auch Auftragsdetails, als auch....
Der jeweils durch das vorbereitete dynamische Select
gefundene Satz soll dann, wenn man so will, als
großer String zurückgeliefert werden.
Um die Auswertung des Strings (von 1-6 Kundennummer, von 7-16 Kurzname,...) kümmern wir uns dann selbst.
Aber so wie ich eure Antworten verstanden habe, führt wohl kein Weg an einem externen Programm vorbei.
Danke euch!
lg
Chris

caltmann
10-12-08, 10:53
Hhhmm.. da hab' ich wohl was falsch interpretiert.

[...]
>Warum schmeißt ihr nicht gleich alle Daten auf einen großen
>sequentiellen Haufen, dann spart ihr euch doch viel
>Aufwand?!
[...]

Genau das ist der Punkt:
WIR geben den Aufbau der Tabelle nicht vor,
können aber zur Laufzeit den Aufbau auslesen.
D.h., wenn wir die Daten in einer "Wurst" bekommen,
wüssten wir ab wo welches Feld beginnt.
Nachdem SQL aber gewisse Prüfungen zur Laufzeit
durchführt (Thema: Datentypen),
geht das mittels embedded SQL
so ja nicht. Oder gibt es ein "prepared" Fetch oder dergl.?
Meine Erfahrung beschränken sich leider bisher auf das verwenden von SQL mittels "normalen" Zugriffen,
wo alle Details bekannt sind (Aufbau und Host-Variablen).
Derart "generisch" ist für mich auch Neuland, für diesen
Fall aber nötig, auch wenn es heißt eine Ebene tiefer
zu gehen, oder andere Programmiersprachen zu nutzen,
sowie selbst zwischen Datentypen herumzukonvertieren.
Nachdem ich mit VARPG in Verbindung mit SQL aber so
gut wie keine Erfahrung habe, wollte ich das Feld einmal
abstecken,
bevor wir später draufkommen, dass es ohnehin auch
mit Bordmitteln gegangen wäre.

Danke +lg
Chris

Fuerchau
10-12-08, 11:25
Da stellt sich mir nun die Frage, wie die Daten nun tatsächlich vorliegen.
Hast du hier ggf. mal ein Beispiel ?

Normalerweise würde ich ein Import-Programm entwickeln, dass die vorliegenden Daten interpretiert und gezielt in entsprechende DB-Tabellen kopiert, so dass die Anwendung sich damit nicht mehr rumschlagen muss und mit normalen SQL's die Zugriffe durchführt.

caltmann
10-12-08, 11:46
Konkretes Beispiel habe ich leider keines, im Prinzip sind
die Daten aber ganz "normale" SQL-Tabellen.
Die Vorgabe ist aber, mit nur EINEM Programm, ALLE Tabellen
auslesen zu können. D.h. dieses eine Lese-Programm wird - wenn man so will - von unterschiedlichsten Bildschirmen aufgerufen und soll dann den durch den Select Cursor
gefundenen Satz als Datenwurst zurückliefern, unabhängig
von der Anzahl der Felder, Datentypen und Aufbau.
Es wird dann ein String mit maximaler Länge im Programm
vorgesehen, um die Auswertung des Datenstrings kümmert
sich dann ein anderes Programm.
Kann gut sein, dass sich sowas mit SQL gar nicht realisieren läßt, das bin ich eben gerade am erforschen.
Nachdem andere Entwicklungsumgebungen aber Datawindows/-Areas/-Grids o.Ä. unterstützen, lassen sich dann hier vielleicht
so in einer Schleife die Spalten durch Konvertieren zusammen"stringen", damit der VARPG damit gefüttert werden kann.
Also VARPG-GUI sendet "Select X from Y... " an das
"Connector"-DLL, dies schickt dann die gewünschten Spalten
in einer Wurst zurück, und das VARPG-GUI, welches den Aufbau ja kennt (aber eben erst zur Laufzeit, da es für unterschiedliche Tabellen verwendet wird), analysiert den
String und stellt die Daten am Bildschirm dar.
Mit OVRDBF, LVLCHK(NO) und einer Dummy-Datei geht das ohne SQL bereits sehr gut.
Voraussetzung ist hier aber, dass der
Satzformatname zum Kompilationszeitpunkt bekannt ist.
Nachdem dies bei einzelnen Tabellen nicht vorausgesetzt
werden kann, der Satzformatname aber nicht dynamisch
sonder fix sein muss, war unser Ansatz, es über den SQL-Weg
zu versuchen. Für andere Vorschläge sind wir natürlich
gerne offen.

Ich Hoffe es hilft zum besseren Verständnis.
lg
Chris