Rekursive Prozedur

  • SQL

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von MarvinKleinMusic.

    Rekursive Prozedur

    Hallo zusammen,

    ich wollte mal nachfragen, ob Jemand von euch eine Möglichkeit kennt, innerhalb einer Prozedur Rekursiv abfragen auszuführen.

    Hintergrund ist, dass ich anhand einer Artikelnummer solange selecten möchte, bis ich alle Artikel aus der Stückliste bekommen habe.

    Beispiel:
    ARTIKEL1 ist eine Stückliste und besteht aus den Artikeln:
    A1
    B1
    C1

    Nun ist B1 wieder eine Stückliste und besteht aus:
    D1
    E1

    Mein Resultat sollte nun so aussehen:

    HAUPTARTIKEL;UNTERARTIKEL;
    A1;NULL
    B1;D1;
    B1;E1;
    C1;NULL

    Hat Jemand eine Idee, wie sich das realisieren lässt?

    LG Marvin
    Also Dein Artikel ist quasi ein Konzept, das auf sich selbst mit einer 0..*-Assoziation zeigt. Entsprechend kannst Du ja dann eine Methode entwerfen, die erstmal die Basisartikel findet und dann auf jedem dieser Artikel eine rekursive Funktion aufrufen, die dann eine entsprechende Formatierung zurückgibt und diese dann noch anpassen. Innerhalb der rekursiven Funktion gehst Du dann halt alle Kinder-Artikel durch mit Abbruchbedingung, dass keine vorhanden sind.
    Edit: Ach mist. Ich war auf Anwendungsebene. Es geht um SQL, oder? Da wäre es dann ganz gut mal Deine bisherigen Definitionen bzw. Tabellenstrukturen zu sehen. Auch die aktuelle Abfrage.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Hallo Trade,

    ja es geht um SQL. In C# wüsste ich direkt wie es geht ;)

    Die Struktur sieht wie folgt aus:


    Tabelle1: Belegpos:
    BUCHUNG_BPOSNR
    BPOS_A_ARTIKELNR
    BPOS_N_MENGE

    Tabelle2 Artikelstueckliste:
    ARST_A_HAUPTARTIKEL
    ARST_A_UNTERARTIKEL
    ARST_N_MENGE

    Ich Springe von Belegpos nach Artikelstückliste. Dabei Gilt BPOS_A_ARTIKELNR = ARST_A_HAUPTARTIKEL. Es kann sein, dass eine Position keine Stückliste ist, dann wäre auch kein Eintrag für die Artikelnummer in Artikelstueckliste.

    Nun muss ich Für jeden Unterartikel in Artikelstueckliste wieder in auf ARST_A_HAUPTARTIKEL joinen, bis ARST_A_UNTERARTIKEL nicht mehr als ARST_A_HAUPTARTIKEL gefunden wird.
    Siehe:


    Dann zu



    Als Ergebnis sollte dabei folgendes herauskommen:
    HAUPTARTIKEL;UNTERARTIKEL;MENGE
    VP-700-SH01PA;NULL;1 (Aus Tabelle Belegpos)
    VP-700-AS14A;VP-700_C; 1 (Aus Tabelle Artikelstueckliste)
    VP-700-AS14A;VP-700_M; 1 (Aus Tabelle Artikelstueckliste)
    VP-700-AS14A;VP-700_Y; 1 (Aus Tabelle Artikelstueckliste)
    VP-700-AS14A;VP-700_B; 1 (Aus Tabelle Artikelstueckliste)
    VP-700-AS14A;VP-700_B; 1 (Aus Tabelle Artikelstueckliste)

    LG Marvin
    Also unabhängig davon, ob die Architektur dann gut ist oder nicht (kann ich jetzt so nicht beurteilen): Hier könnte eine Common Table Expression helfen, die dann einen rekursiven Self-Join ausübt.
    Ich kann jetzt nichts genaues hinzimmern aus dem Stegreif, aber sowas in der Art:

    SQL-Abfrage

    1. ​WITH q AS
    2. (
    3. SELECT ARST_A_HAUPTARTIKEL, ARST_A_UNTERARTIKEL, ARST_N_MENGE
    4. FROM Artikelstueckliste
    5. /* Hier eine Bedingung noch rein für die grundlegenden Ancestor */
    6. UNION ALL
    7. SELECT a.ARST_A_HAUPTARTIKEL, a.ARST_A_UNTERARTIKEL, a.ARST_N_MENGE
    8. FROM Artikelstueckliste a
    9. JOIN q
    10. ON a.ARST_A_HAUPTARTIKEL = q.ARST_A_UNTERARTIKEL
    11. )
    12. SELECT *
    13. FROM q;


    Dann müsste man quasi nur noch schauen, wie bzw. dass man den Join auf Belegpos noch anhängt. Allerdings ist das wohl sehr ineffizient, wenn erst alles aufeinander gejoint wird und nicht anfangs schon gefiltert wird. Da müsste man sich was überlegen.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Hallo Trade,

    erstmal danke für deine Antwort.

    Wenn ich das richtig verstanden habe, dann muss ich bei der noch einzufügenden Bedigung meinen Startartikel angeben, korrekt?

    SQL-Abfrage

    1. WITH q AS
    2. (
    3. SELECT ARST_A_HAUPTARTI, ARST_A_UNTERARTI, ARST_N_MENGE
    4. FROM ARTIKELSTUECKLISTE
    5. WHERE ARST_A_HAUPTARTI = 'VP-700-AS14A'
    6. UNION ALL
    7. SELECT a.ARST_A_HAUPTARTI, a.ARST_A_UNTERARTI, a.ARST_N_MENGE
    8. FROM ARTIKELSTUECKLISTE a
    9. JOIN q
    10. ON a.ARST_A_HAUPTARTI = q.ARST_A_UNTERARTI
    11. )
    12. SELECT * FROM q;


    Nun bekomme ich aber immer:
    Dynamic SQL Error SQL error code = -104 CTE 'Q' has cyclic dependencies

    SQL-Abfrage

    1. SELECT ARST_A_HAUPTARTI, ARST_A_UNTERARTI, ARST_N_MENGE
    2. FROM ARTIKELSTUECKLISTE
    3. WHERE ARST_A_HAUPTARTI = 'VP-700-AS14A'


    Liefert folgendes Ergebnis:


    LG Marvin