Das Forentreffen 2018 findet am 20./21. April in Dresden statt. Weitere Infos hier
Zur Homepage des Deutschsprachige Xbase-Entwickler e. V.
Xbase++-Wiki des Deutschsprachige Xbase-Entwickler e. V.

Stored Procedures in komplexen SQL Statements

Advantage Database Server

Moderator: Moderatoren

Antworten
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2450
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Kontaktdaten:

Stored Procedures in komplexen SQL Statements

Beitrag von UliTs » Do, 28. Sep 2017 11:26

Hallo allerseits,

ich habe eine ziemlich aufwendige Stored Procedure geschrieben, die eine einzeilige Tabelle als Rückgabe liefert:

Code: Alles auswählen

create procedure FAuPrio( FAuId Integer, Prio Integer output, Liefertermin date output ) ...
Aufrufen kann man diese z.B. durch:

Code: Alles auswählen

execute procedure FAuPrio( 12345/*FAuId*/ );
Jetzt habe ein SQL Statement (Statement ist eigentlich viel komplizierter) über die Tabelle FAu (welche die FAuId enthält):

Code: Alles auswählen

select FAu.* from FAu
Dieses möchte ich um die Spalten Prio und Liefertermin (also die Ergebnisspalten der stored procedure erweitern.
Wie mache ich das? Folgende Lösung funktioniert leider nicht (FAuId nicht bekannt):

Code: Alles auswählen

select FAu.*,
       (select FAuPrio.Prio from( execute procedure FAuPrio( FAu.FAuId ) ) FAuPrio) Prio,
       (select FAuL.Liefertermin from( execute procedure FAuPrio( FAu.FAuId ) ) FAuL) Liefertermin
from   FAu
Ich habe eine Lösung, bei der ich Funktionen geschrieben habe:
create function FAuFunctionPrio( nFAuId integer ) returns integer
begin
return( (select FAuPrio.Prio from (execute procedure FAuPrio( nFAuId )) FAuPrio) );
end;

create function FAuFunctionLiefertermin( nFAuId integer ) returns date
begin
return( (select FAuPrio.Liefertermin from (execute procedure FAuPrio( nFAuId )) FAuPrio) );
end;
Dann funktioniert das Statement:

Code: Alles auswählen

select FAu.*,
       FAuFunctionPrio( FAu.FAuId ) Prio,
       FAuFunctionLiefertermin( FAu.FAuId ) Liefertermin
from   FAu
wie gewünscht.
Nachteil: je Zeile wird bei Aufruf der Funktionen die stored procedure 2x aufgerufen.
Gibt es eine Lösung, bei der der ADS mit einem Aufruf je Zeile auskommt (ist sehr rechenintensiv, würde die Rechenzeit halbieren!)?
Vielleicht mit Hilfe von Joins?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück

Benutzeravatar
nightcrawler
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 272
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72181 Starzach
Kontaktdaten:

Re: Stored Procedures in komplexen SQL Statements

Beitrag von nightcrawler » Do, 28. Sep 2017 15:22

Code: Alles auswählen

SELECT A.*, B.* FROM
  FAU A, (execute procedure FAuPrio( A.FAuId )) B
  WHERE A.FAuId=B.FAuId
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de

UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2450
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Kontaktdaten:

Re: Stored Procedures in komplexen SQL Statements

Beitrag von UliTs » Mi, 04. Okt 2017 10:15

Hallo Joachim,

danke für die Nachricht und Idee.
Leider ist auch bei Deinem Statement A.FAuId als Parameter der Stored Procedure "unbekannt". :-( .

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück

Benutzeravatar
nightcrawler
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 272
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72181 Starzach
Kontaktdaten:

Re: Stored Procedures in komplexen SQL Statements

Beitrag von nightcrawler » Fr, 06. Okt 2017 11:51

Hallo Uli,
ich glaube, ich weiß warum ... eine Stored Procedue kann auch keinen oder mehrere Datensätze zurückliefern, eine Function nicht. Daher wird es wohl verhindert sein, die Stored Procedure wie in meinem Statement vorgeschlagen zu verwenden.
Hast Du denn immer die gesamte Tabelle FAu in der Abfrage? Dann würde ich die Stored Procedure umschreiben und dabei FAuID als OUTPUT statt INPUT parameter verwenden.
Eine andere Möglichkeit wäre eine Temp-Tabelle:

Code: Alles auswählen

create procedure FAuPrio( FAuId output, Prio Integer output, Liefertermin date output )
BEGIN
  DECLARE @tab CURSOR AS SELECT FAUID FROM #mytmp;
  WHILE FETCH @tab DO
    // Rechnung
    INSERT INTO __output (FAUID, Prio, Liefertermin) VALUES (@tab.FAUID, ....);
  END;
  CLOSE @tab;  
END;
Verwendung:

Code: Alles auswählen

TRY drop table #mytmp; CATCH ALL END;
SELECT FAUID INTO #mytmp FROM FAU WHERE ....;  //irgendwas sinnvolles
EXECUTE PROCEDURE FAuPrio();
nicht vergessen ... Du musst #mytmp auch wieder schliessen bzw löschen vor dem nächsten Durchlauf;)
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de

Antworten