-
ILE RPG und dynamisches Array
Hallo,
ich versuche mich gerade an emb SQL mit Variablenübergabe über ein dyn. Array. Ich bekomme jedoch die Fehlermeldung:
PHP-Code:
*RNF0528 20 138 004500 Index ist für einen Namen, der keine Feldgruppe ist, nicht zulässig; der Index wird ignoriert.
Bei: Array(i)=FETCHDS
Hier der gesamte Code:
PHP-Code:
H DftActGrp(*NO) ActGrp(*CALLER) H alwnull(*USRCTL) D/COPY LIB/FILE,MEMBER DAUFNEHM PR EXTPGM('SQLSAMPLE4') D PARM1 like(Array2) D PARM2 1A DAUFNEHM PI D Array like(Array2) D fcall 1A DArrayptr S * Inz(*Null) DArray2 DS Dim(32767) Based(Arrayptr) D likeds(DSLIB) Di S 5S 0 inz(1) Dj S 5S 0 inz(1) DFetchds DS likeds(DSLIB) C/EXEC SQL C+ Declare MyCsr Cursor for C+ Select * From LIB/FILE C/End-Exec C/EXEC SQL C+ Open MyCsr C/END-EXEC /FREE Arrayptr = %Alloc(%Size(Array) * i); /END-FREE C do *HIVAL C/EXEC SQL C+ Fetch MyCsr C+ into :FETCHDS C/END-EXEC C if SQLCOD = 100 C or SQLCOD < *ZEROS C eval fcall='E' C leave C endif C eval Array(i)=FETCHDS /Free Arrayptr = %Realloc(Arrayptr: %Size(Array) * i); /END-FREE C eval i=i+1 C enddo C/EXEC SQL C+ Close MyCsr C/END-EXEC C return
Ich hätte auch noch eine Frage. Und zwar geht diese Übergabe so wenn das Array in VARP auch so definiert ist wie dieses?(mit dem Pointer und dim(32767) ) Oder wie müsste ich es definieren, denn ich weiß ja nicht wie groß das Array ist das ich zurückgebe. feste Werte sind schlecht weil sie entweder zu groß oder zu klein sind. Darum wollte ich es mit einem Dynamischen Array machen.
Gruß Martin
-
Dynamische Arrays gibts in RPGLE nicht.
Beim Fetch musst du noch "for n rows" angeben, damit das Array gefüllt wird.
Ich glaube in SQLERR3 steht dann die Anzahl der gelesenen Sätze.
Das Ganze nennt man im Übrigen Block-Fetch.
Ansonsten berechne mal die Größe für deinen Alloc, der darf 16MB nicht übersteigen.
-
Wenn es dyn. Array in ILE RPG nicht gibt warum schimpft der Compiler dann nicht bei dem Alloc? Zzt. sieht es ja nur so aus als ob es Probleme beim hin und herschieben des Arrays geben würde. (Und jetzt beim korrekten Zuweisen der Daten)
EDIT: Ich habe mir gerade mal den Block-Fetch angeschaut. Nur in welches Array schreibt er die Row(in Array(1) 2,3,...,zb bei for 1 row)? Angabe der Row ist ja nicht erlaubt.
Zitat von Fuerchau
Dynamische Arrays gibts in RPGLE nicht.
Beim Fetch musst du noch "for n rows" angeben, damit das Array gefüllt wird.
Ich glaube in SQLERR3 steht dann die Anzahl der gelesenen Sätze.
Das Ganze nennt man im Übrigen Block-Fetch.
Ansonsten berechne mal die Größe für deinen Alloc, der darf 16MB nicht übersteigen.
-
Stimmt, er startet immer beim 1. Element.
Und was deinen ALLOC angeht, klar streikt der nicht. Deine Tabelle ist aber immer noch 32767 Elemente lang. Du bekommst nur beim Zugriff auf die Variablen einen MCH. Du kannst sogar auf fremde Speicherbereiche kommen.
Wichtig ist, dass du bei den %lokup, %sort usw. immer die Anzahl Elemente angibst, sonst knallst.
Das ist das Gleiche, wie die Definition eines Übernahme-Parameters (*ENTRY, PLIST) in Ausprägung X, und zur Laufzeit dann CALL mit Y.
Der Compiler kann das nicht prüfen.
-
Ja richtig dynamisch ist das Array nicht, aber ansatzweise bis zu der maximalen Größe.
Eine Frage hätte ich noch und zwar habe ich ja bei PR/PI meine Arrays mit like (Array2) definiert. Dh sie müssten(?) doch auch Arrays mit einer Größe von X sein(je nachdem wie groß ich Array2 definiert habe) oder? Warum sagt er dann ein Index sei nicht zulässig?
Zitat von Fuerchau
Stimmt, er startet immer beim 1. Element.
Und was deinen ALLOC angeht, klar streikt der nicht. Deine Tabelle ist aber immer noch 32767 Elemente lang. Du bekommst nur beim Zugriff auf die Variablen einen MCH. Du kannst sogar auf fremde Speicherbereiche kommen.
Wichtig ist, dass du bei den %lokup, %sort usw. immer die Anzahl Elemente angibst, sonst knallst.
Das ist das Gleiche, wie die Definition eines Übernahme-Parameters (*ENTRY, PLIST) in Ausprägung X, und zur Laufzeit dann CALL mit Y.
Der Compiler kann das nicht prüfen.
-
Hi,
bei der Definition über Like(Array) wird nur die Feld-Beschreibung, nicht jedoch die Anzahl der Feldgruppen-Elemente definiert, d.h. Du musst jeweils die (maximale) Anzahl der Feldgruppen-Elemente angeben, z.B. DIM(9999).
Birgitta
-
Bei der Übergabe von Arrays musst du aber gaaaaaaanz vorsichtig sein.
Wenn du nämlich die Anzahl der Elemente nicht irgendwo austauschst wirst du später schwere Pufferüberschreibungen riskieren.
Gut, im Gegensatz zu Microsoft wird das nie zu ausführbarem Code führen, aber wenn du da in VARPG bist, wer weiß welche Tricks für Viren es da gibt.
Aber ehrlich:
Wenn du einer Prozedur ein Array übergibst, dann musst du ihm auch sagen wieviele Element da drin sind.
Umgekehrt gilt natürlich das selbe.
-
Hallo,
Ja das mit den Dim(XYZ) hatte ich gestern abend durch ausprobieren noch herausgefunden. Mit einem fest definiertem Array funktioniert es jetzt.
Ich kann der Methode nicht sagen wieviele Elemente das Array genau hat, da der SQL und die Allocierung ja dort stattfindet. Die Frage wäre ob ich das Array gefahrenfrei einfach so zurückgeben kann, bzw ob das überhaupt so funktioniert. Das Array in VARPG wurde zwar auch auf die max. Größe definiert es wurde jedoch noch kein Speicher allociert, da ich ja nicht weiß wieviel ich allocieren müsste.
Gruß Martin
-
Das Übergeben von ARRAYS ist natürlich sehr kritisch zu betrachten, da RPG eben keine Dynamik kennt.
Egal ob du den Parameter verändert oder einen "return variable" kodierst, im Zusammenspiel VARPG (Client) und AS/400-Programm wird generell die definierte Struktur übertragen !
Also:
Wenn VARPG als Parameter ein Array mit 1000 Elementen übergibt, weiß der Compiler, dass eine Speicherbereich von 1000 Elementen zu übertragen ist.
Der Service gibt dann andererseits den selben Speicherbereich auch wieder zurück, und zwar unabhängig davon, ob dieser auch tatsächlich verändert wurde (ich glaub nicht, dass dort ein Before-/Afterimmage-Abgleich stattfindet).
Es gibt also generell einen Unterschied zwischen einem lokalen Call der tatsächlich per Reference Parameter austauscht und einem Remote-Call, der Parameter ja übers Netzwerk austauscht.
Da empfehle ich dir eher wieder SQL !
Definiere eine externe Prozedur, die du mit Parametern aufrufst und die dir ein Resultset zurückgibt (was dann auch ein Array sein kann, siehe "SET RESULTSET").
-
Ich benutze ja SQL wollte mir nur die verschiedenen Möglichkeiten der Rückgabe anschauen, vergleichen und mir dann das Beste heraussuchen. Die Methode mit festen Arrays und Schaltern (Mehrmalsaufruf, einmal pro Satz) funktioniert ganz gut ich wollte mich nur noch weiter umschaun.
Gruß Martin
Similar Threads
-
By homue in forum NEWSboard Programmierung
Antworten: 5
Letzter Beitrag: 18-07-07, 16:47
-
By Stoeberl in forum NEWSboard Programmierung
Antworten: 8
Letzter Beitrag: 10-01-07, 10:58
-
By Squall in forum IBM i Hauptforum
Antworten: 82
Letzter Beitrag: 19-10-06, 15:37
-
By Squall in forum IBM i Hauptforum
Antworten: 31
Letzter Beitrag: 28-09-06, 17:53
-
By Angela in forum IBM i Hauptforum
Antworten: 4
Letzter Beitrag: 22-08-06, 10:11
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks