Einzelnen Beitrag anzeigen

Nightfly

Registriert seit: 25. Mär 2004
Ort: Dresden
118 Beiträge
 
#1

Rekursion in StoredProcedure vermeiden,aber wie

  Alt 31. Mär 2004, 12:50
Hi

ich kömpfe immer noch mit meiner doch jetzt schon recht großen Prozedur. Leider ist meine bisher einzige lösung,das sie sich selbst rekursiv aufruft,aber das ist wohl tödlich (und verursacht die fehlermeldung "too many concurrent executions of the same request"
Die Prozedur berechnet Summenzeilen aus rechnungen. Das ist auch kein Problem. Bloß wenn aus diesen Summenzeilen wieder summen gebildet werden sollen, stoße ich an meine Grenzen. denn diese "2 generation summenzeilen" kann ich nicht aus den rechnungen berechen, sondern aus der "ersten generation" summenzeilen...

SQL-Code:
CREATE PROCEDURE SUMMIEREN (
    STELLE CHAR(9),
    JAHR INTEGER)
RETURNS (
    BEREICH INTEGER,
    BEZ CHAR(32),
    ALLES FLOAT,
    JAN FLOAT,
    FEB FLOAT,
    MAR FLOAT,
    APR FLOAT,
    MAI FLOAT,
    JUN FLOAT,
    JUL FLOAT,
    AUG FLOAT,
    SEP FLOAT,
    OKT FLOAT,
    NOV FLOAT,
    DEZ FLOAT)
AS
DECLARE VARIABLE SUBTRAHEND INTEGER;
DECLARE VARIABLE MINUEND INTEGER;
DECLARE VARIABLE ANZAHL INTEGER;
DECLARE VARIABLE DIF2 INTEGER;
DECLARE VARIABLE DIF1 INTEGER;
DECLARE VARIABLE ISINHAUPTKEYS INTEGER;
begin
  for select ID,BEZ from MAIN B where B.STELLE = :STELLE order by id
  into :BEREICH, :BEZ do
  begin
    select count(*) from vorgabe where ID = :bereich into :Anzahl;
    if (:ANZAHL = 1) then
    begin /* die direkten parents berechnen */
    select count(*) from hauptkeys where ID = :bereich into :ISINHAUPTKEYS;
    if (:ISINHAUPTKEYS = 1) then
      begin
      select sum(R_ANZ * R_EPREIS) from RECHNUNG R, MAIN M
      where (R.stelle = :Stelle) and (M.stelle = R.Stelle) and (R.bereich = M.ID) and (M.parent = :BEREICH) and (EXTRACT(YEAR from R.R_Datum) = :Jahr) and (EXTRACT(MONTH from R.R_Datum)=1)
      into :JAN;
      select sum(R_ANZ * R_EPREIS) from RECHNUNG R, MAIN M
      where (R.stelle = :Stelle) and (M.stelle = R.Stelle) and (R.bereich = M.ID) and (M.parent = :BEREICH) and (EXTRACT(YEAR from R.R_Datum) = :Jahr) and (EXTRACT(MONTH from R.R_Datum)=12)
      into :DEZ;
      suspend;
      end
    else
       begin /* "=" zeilen berechnen */
       select max (id) from hauptkeys where id < :bereich into :minuend;
       select parent from hauptkeys where id = :bereich into :subtrahend;
        select JAN from SUMMIEREN(:stelle, :jahr) where (bereich = :minuend) into dif1;
        select JAN from SUMMIEREN(:stelle, :jahr) where (bereich = :subtrahend) into dif2;
        JAN = :DIF1 -:DIF2;
       suspend;
       end
     end
    else
    begin
      select sum(R_ANZ * R_EPREIS) from RECHNUNG R
      where (R.bereich = :BEREICH) and (R.stelle = :Stelle) and (EXTRACT(YEAR from R.R_Datum) = :Jahr) and (EXTRACT(MONTH from R.R_Datum)=1)
      into :JAN;
      select sum(R_ANZ * R_EPREIS) from RECHNUNG R
      where (R.bereich = :BEREICH) and (R.stelle = :Stelle) and (EXTRACT(YEAR from R.R_Datum) = :Jahr) and (EXTRACT(MONTH from R.R_Datum)=12)
      into :DEZ;
      suspend;
    end
  end
end

Das Problem ist der rekursive Aufruf bei /* "=" zeilen berechnen */ Dieser wäre im Grunde nicht nötig, denn die dort geholten werte,die dif1 und dif2 zugewiesen werden, sind in der aktuellen instanz schon fertig berechnet und vorhanden,aber ich komm ja nicht mehr an die ran. oder doch?
Oder gibts ne elegantere Lösung?
  Mit Zitat antworten Zitat