[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    May 2009
    Beiträge
    52

    SQLRPGLE Rekursive Funktion

    Hallo Leute,

    kann man in einem SQLRPGLE eine Funktion rekursiv aufrufen mit neuen ResultSet dieser Ebene?
    Der declarte Cursor ist wohl global, wie schaff ich es dass dieser nur in der jeweils offenen Rekursionsstufe verwendet wird?


    PHP-Code:
    Beispiel:
    GETSTUECKLISTE(TEIL)
     -> 
    Fetch auf die Teile abc
       
    -> je Teil GetStueckliste(a)
         -> 
    Fetch aus a mit  de
    Eine Lösung wäre nicht jeden einzelnen Record zu fetchen sondern gleich in ein Array-Zwischenspeicher zu stellen und in der nächsten Rekursionsstufe den Cursor neu zu öffnen.

    ..oder einfach nicht Rekursiv auflösen ^^

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    SQL-Cursor können leider nicht rekursiv verwendet werden, da der Name ja nur 1 Mal existiert.

    Für deine Funktion würde ich da eher eine "Rekursive CTE" verwenden, damit kannst du die Stückliste per SQL in einem Cursor komplett lesen.

    Beispiele findest du hier im Forum und in der SQL-Reference.
    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
    Mar 2002
    Beiträge
    5.365
    Zitat Zitat von MGJ79 Beitrag anzeigen
    Hallo Leute,

    kann man in einem SQLRPGLE eine Funktion rekursiv aufrufen mit neuen ResultSet dieser Ebene?
    Der declarte Cursor ist wohl global, wie schaff ich es dass dieser nur in der jeweils offenen Rekursionsstufe verwendet wird?


    PHP-Code:
    Beispiel:
    GETSTUECKLISTE(TEIL)
     -> 
    Fetch auf die Teile abc
       
    -> je Teil GetStueckliste(a)
         -> 
    Fetch aus a mit  de
    Eine Lösung wäre nicht jeden einzelnen Record zu fetchen sondern gleich in ein Array-Zwischenspeicher zu stellen und in der nächsten Rekursionsstufe den Cursor neu zu öffnen.

    ..oder einfach nicht Rekursiv auflösen ^^
    mit ACTGRP(*NEW) müsste das gehen, falls dem maroden Precompiler dabei nicht schwindelig wird...
    Ansonsten bleibt noch Baldur's Vorschlag oder CLI

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    ACTGRP(*NEW) geht hier nicht, da die Funktion sich ja selber aufrufen soll.
    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
    Mar 2002
    Beiträge
    5.365
    Zitat Zitat von Fuerchau Beitrag anzeigen
    ACTGRP(*NEW) geht hier nicht, da die Funktion sich ja selber aufrufen soll.
    ... das halte ich erstens für ein Gerücht und zweitens könnte man da ja auch noch einen Aufruf zwischenschalten.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Zitat Zitat von MGJ79 Beitrag anzeigen
    ...oder einfach nicht Rekursiv auflösen ^^
    Falls Ihr auf Release 7.1 (TR3) oder höher seid, kann anstatt der Rekursiven Common Table Expression (RCTE) auch die Hierarchische Query Anweisung verwendet werden und die Stückliste damit auflösen.

    Hierarchische Query Anweisungen sind einfacher zu verstehen als RCTEs.
    Nähere Informationen kannst Du hier nachlesen:

    Hierarchical Queries with DB2 Connect By
    A new method for recursively processing data relationships

    Auf Deutsch gibt's wurden ähnliche Artikel im (kostenpflichtigen) TechKnowLetter (vom Midrange Magazin) veröffentlicht.

    Birgitta
    Birgitta Hauser

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

  7. #7
    Registriert seit
    May 2009
    Beiträge
    52

    Endergebnis

    Hallo Zusammen,

    vielen Dank für die Infos als CTE könnte man es wie folgt lösen:
    Code:
    DECLARE CSR01 CURSOR FOR 
      With RPL (level, TSTNRK, TSSTNK, TSMENG) As (              
         (Select 1, ROOT.TSTNRK, ROOT.TSSTNK, ROOT.TSMENG        
          From HTSLSP ROOT where                                 
          TSTNRK = :XX_KEY )                                     
      Union All                                                  
       (Select PARENT.level+1,                                   
        CHILD.TSTNRK, CHILD.TSSTNK, CHILD.TSMENG * PARENT.TSMENG 
            From RPL PARENT, HTSLSP CHILD                        
             Where PARENT.TSSTNK = CHILD.TSTNRK)                 
      ) Select TSSTNK, Sum(TSMENG) As TSMENG From RPL            
      Group By TSSTNK
    .. da ich aber Transparenz bevorzuge und hier die Gefahr von Endlosrekursion besteht, habe ich mich für folgenden Weg entschied:

    - Auflösung über Rekursive RPG_Funktion
    - Übergabe einer DS-Array
    - jede Ebene wird über ein SQL aufgelöst welches die Daten in ein temp. Array "entläd" da der Cursor quasi Global geöffnet ist.

  8. #8
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Der SQL ist doch "transparent", erleichtert die Verarbeitung und SQL verhindert automatisch eine Endlosrekursion.
    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

  9. #9
    Registriert seit
    Apr 2013
    Beiträge
    6
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Der SQL ist doch "transparent", erleichtert die Verarbeitung und SQL verhindert automatisch eine Endlosrekursion.
    vermutlich ist eine In-Sich-Verwendung in der Stückliste gemeint. Dagegen ist SQL wohl noch machtlos, ist eben keine richtige Sprache

  10. #10
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Zitat Zitat von Alfred E. Neumann Beitrag anzeigen
    vermutlich ist eine In-Sich-Verwendung in der Stückliste gemeint. Dagegen ist SQL wohl noch machtlos, ist eben keine richtige Sprache
    Mit SQL können sehr wohl wechselseitige Abfragen gemacht werden, ohne dass man in eine Endlosschleife läuft.

    Dazu muss lediglich die Anweisung CYCLE zwischen der CTE und der endgültigen SELECT-Anweisung eingefügt werden.

    Hier ein Beispiel einer Auswertung mit wechselseitigen Beziehungen - Fahrpläne (ohne Endlos-Schleife).
    Code:
    With Destinations (Departure, Arrival, Connections, Costs) 
      as (Select Departure, Arrival, 
                 Cast(Departure concat '->' concat Arrival as VarChar(200)),
                 Price
             From Flights f
             Where Departure ='Frankfurt'
          Union All
          Select d.Departure, f.Arrival, 
                 Cast(d.Connections concat '->' concat f.Arrival as VarChar(200)),
                 Costs + Price
             From Destinations d join Flights f on d.Arrival = f.Departure
           Where d.arrival <> 'Frankfurt')
          Cycle Arrival set cyclic_data to '1' Default '0'
    Select Departure, Arrival, Connections, Costs 
       From Destinations
    Where cyclic_data = '0'
    order by departure, arrival
    Birgitta
    Birgitta Hauser

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

  11. #11
    Registriert seit
    Apr 2013
    Beiträge
    6
    Zitat Zitat von B.Hauser Beitrag anzeigen
    Mit SQL können sehr wohl wechselseitige Abfragen gemacht werden, ohne dass man in eine Endlosschleife läuft.

    Dazu muss lediglich die Anweisung CYCLE zwischen der CTE und der endgültigen SELECT-Anweisung eingefügt werden.
    Grosse Klasse, vielen Dank!

Similar Threads

  1. SQL: Ausführungsverhalten einer Funktion in einem CASE-Statement
    By mwithake in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 04-08-09, 14:57
  2. Funktion in WRKACTJOB wiederherstellen
    By Marsman in forum NEWSboard Programmierung
    Antworten: 8
    Letzter Beitrag: 27-09-06, 12:32
  3. sql funktion
    By steven_r in forum NEWSboard Programmierung
    Antworten: 1
    Letzter Beitrag: 01-06-06, 12:16
  4. *zoned bei SQLRPGLE Programm
    By Stefan_Sk in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 12-07-05, 13:04
  5. Erstellen Trigger über SQL / Read Funktion
    By GHoffmann in forum IBM i Hauptforum
    Antworten: 0
    Letzter Beitrag: 07-07-05, 09:18

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •