+ Antworten
Ergebnis 1 bis 7 von 7
  1. #1
    Oberbootsmann
    Registriert seit
    04.08.2005
    Beiträge
    995


    Standard [SQL/Oracle] rekursive stored procedure

    moin,

    ich habe ein tabelle mit folgenden spalten:
    kind, vater, menge

    die menge ist eher zu vernachlässigen.

    in dieser SP soll nun rekursiv von einem vater über die kinder gegangen werden und mir am ende eine liste der kinder ausgeben.

    für mich ist das problem, dass ein vater mehr als 1 sohn haben kann, weswegen ich das ergebnis einer einfachen select abfrage nicht einfach in eine variable stecken kann.

    wäre für ideen und lösungsvorschläge sehr dankbar !
    cpu: Core2Duo E6600 @ 3,55ghz - Thermalright Ultra-120 eXtreme Heatsink + Delta FFB 1212 EHE (322m³/h )
    graka: GeForce 8800GT @ 650/950 @AC Accelero S1
    board: Asus P5W DH Deluxe
    ram: 4*2048 Mushkin XP2-6400

  2. Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.

  3. #2
    Bootsmann
    Registriert seit
    30.11.2006
    Beiträge
    743


    Standard

    Willst Du das Ergebnis der Abfrage in deiner stored procedure weiter verarbeiten, oder an den Aufrufenden Prozess zurückgeben?

    Ersteres sollte mit einem cursor for loop funktionieren. Innerhalb der Schleife dann halt die Verarbeitung pro Datensatz.

    Letzteres sollte über einen ref cursor gehen, den man halt für die Abfrage öffnet und dann zurückgibt.

  4. #3
    Oberbootsmann
    Registriert seit
    04.08.2005
    Beiträge
    995
    Themenstarter


    Standard

    nein, es langt wenn es ausgegen wird, wenn die rekursion komplett durch ist.

    ich habe soweit auch schon was geschrieben, allerdings sagt er mir beim versuch der ausführung, dass zu viele cursor offen sind

    das ganze sieht im moment so aus:

    Code:
    create or replace
    procedure viewArticles(ArtID in number) as
      art_id number;
      art_name varchar2(50);
      cursor csr is select father from articles_table at where at.father = ArtID;
    begin
      open csr;
      loop
        fetch csr into art_id;
        exit when csr%notfound;
        select titel into art_name from articles where articles.tid=art_id;
        dbms_output.put_line(art_name);
         viewArticles(art_id);
      end loop;
      close csr;
      return;
    end;
    cpu: Core2Duo E6600 @ 3,55ghz - Thermalright Ultra-120 eXtreme Heatsink + Delta FFB 1212 EHE (322m³/h )
    graka: GeForce 8800GT @ 650/950 @AC Accelero S1
    board: Asus P5W DH Deluxe
    ram: 4*2048 Mushkin XP2-6400

  5. #4
    Bootsmann
    Registriert seit
    30.11.2006
    Beiträge
    743


    Standard

    Zitat Zitat von bluezac Beitrag anzeigen
    nein, es langt wenn es ausgegen wird, wenn die rekursion komplett durch ist.

    ich habe soweit auch schon was geschrieben, allerdings sagt er mir beim versuch der ausführung, dass zu viele cursor offen sind

    das ganze sieht im moment so aus:

    Code:
    create or replace
    procedure viewArticles(ArtID in number) as
      art_id number;
      art_name varchar2(50);
      cursor csr is select father from articles_table at where at.father = ArtID;
    begin
      open csr;
      loop
        fetch csr into art_id;
        exit when csr%notfound;
        select titel into art_name from articles where articles.tid=art_id;
        dbms_output.put_line(art_name);
         viewArticles(art_id);
      end loop;
      close csr;
      return;
    end;
    Da ist aber was doppeltgemoppelt.

    Mal sehen ob ich das so richtig verstanden habe:

    - Du übergibst die ID des Fathers als ArtID
    - in Deinem Cursor ermittelst Du genau diese ID nochmals
    - und die ermittelte ID nutzt Du dann in deiner Abfrage für die Artikel.

    Da kannst Du doch gleich den übergebenen Parameter in der Artikelabfrage nutzen.

    Also z.B. so:

    Code:
    create or replace
    procedure viewArticles(ArtID in number) as
    begin
    
      for c in (
        select titel from articles where tid in = ArtId
      ) loop
      
        dbms_output.put_line(c.titel);
    
      end loop;
    end;

  6. #5
    Oberbootsmann
    Registriert seit
    04.08.2005
    Beiträge
    995
    Themenstarter


    Standard

    mhm es ist so, dass ein vater ein oder mehrere söhne haben kann.
    diese söhne allerdings weitere söhne. (ich hatte diesen punkt vergessen zu erwähnen)

    also wie eine baumstruktur

    deshalb muss er sich halt mit den gefundenen ids wieder aufrufen.
    cpu: Core2Duo E6600 @ 3,55ghz - Thermalright Ultra-120 eXtreme Heatsink + Delta FFB 1212 EHE (322m³/h )
    graka: GeForce 8800GT @ 650/950 @AC Accelero S1
    board: Asus P5W DH Deluxe
    ram: 4*2048 Mushkin XP2-6400

  7. #6
    Bootsmann
    Registriert seit
    30.11.2006
    Beiträge
    743


    Standard

    Ah, ok, ich habe den rekursiven Aufruf übersehen.

    So wie er im Moment in Deinem Code drinsteht, ist es klar das irgendwann zu viele Cursor geöffnet sind. Du übergibst ja da nicht die ID des Kindes erneut an Deine Procedure, sondern immer wieder die ID des Vaters, also jene ID mit der Du die Procedure ganz zu Anfang aufgerufen hast. Und so kommst Du natürlich nie aus Deiner Schleife raus. Das ist also eigentlich keine Rekursion, sondern eine endlose Wiederholung.

    Da ich Deine Tabellenstruktur jetzt nicht kenne, kann ich nur mutmaßen:

    Code:
    create or replace
    procedure viewArticles(ArtID in number) as
    begin
    
      for c in (
        select id, titel from articles where tid in = ArtId
      ) loop
      
        dbms_output.put_line(c.titel);
    
        viewArticles(c.id);
    
      end loop;
    end;
    Damit übergibst Du die ArtikelID des Kindes als neue VaterID an Deine Procedure.

  8. #7
    Kapitän zur See
    Registriert seit
    17.08.2006
    Beiträge
    3.510


    Standard

    Dafür nimmt man keine Stored Procedure. Die Lösung trägt den Namen "Hierarchische Abfrage".

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein