[SQL/Oracle] rekursive stored procedure

bluezac

Enthusiast
Thread Starter
Mitglied seit
04.08.2005
Beiträge
1.192
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 !
 
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
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.
 
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;
 
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;
 
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.
 
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.
 
Dafür nimmt man keine Stored Procedure. Die Lösung trägt den Namen "Hierarchische Abfrage".
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh