[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Sep 2006
    Beiträge
    132

    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 Namender keine Feldgruppe istnicht 
                               zulässig
    der Index wird ignoriert
    Bei: Array(i)=FETCHDS

    Hier der gesamte Code:
    PHP-Code:
    H DftActGrp(*NOActGrp(*CALLER)                                 
    H alwnull(*USRCTL)                                               
                                                                     
    D/COPY LIB/FILE,MEMBER                                  
                                                                     
    DAUFNEHM          PR                  EXTPGM
    ('SQLSAMPLE4')       
    D PARM1                               like(Array2)               
    D PARM2                          1A                              
                                                                     
    DAUFNEHM          PI                                             
    Array                               like(Array2)               
    D fcall                          1A                              
                                                                     
    DArrayptr         S               
    *   Inz(*Null)                 
    DArray2           DS                  Dim(32767Based(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                              
    CSelect 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

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.243
    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.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Sep 2006
    Beiträge
    132
    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 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.

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.243
    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.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  5. #5
    Registriert seit
    Sep 2006
    Beiträge
    132
    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 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.

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    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
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.243
    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.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  8. #8
    Registriert seit
    Sep 2006
    Beiträge
    132
    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

  9. #9
    Registriert seit
    Feb 2001
    Beiträge
    20.243
    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").
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  10. #10
    Registriert seit
    Sep 2006
    Beiträge
    132
    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

  1. ILE RPG / SQL Füllen einer Feldgruppe
    By homue in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 18-07-07, 16:47
  2. Problem mit Java-Methoden Aufruf aus ILE RPG?
    By Stoeberl in forum NEWSboard Programmierung
    Antworten: 8
    Letzter Beitrag: 10-01-07, 10:58
  3. DDS in ILE RPG
    By Squall in forum IBM i Hauptforum
    Antworten: 82
    Letzter Beitrag: 19-10-06, 15:37
  4. Return ILE RPG
    By Squall in forum IBM i Hauptforum
    Antworten: 31
    Letzter Beitrag: 28-09-06, 17:53
  5. Rechnen mit Datumsfeldern in ILE RPG
    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
  •