Verwendung der gespeicherten Prozedur, die den SETOF-Datensatz in LEFT OUTER JOIN zurückgibt

8

Ich versuche, eine gespeicherte Prozedur aufzurufen, die Parameter in einem linken äußeren Join wie folgt übergibt:

%Vor%

compute_prices() gibt einen Datensatz zurück.
Dies ist die Nachricht Postgres zeigt:

  

FEHLER: Ungültiger Verweis auf FROM-Klauseleintrag für Tabelle "i"

     

... verlassen Sie compute_prices ( i.id , current_date) ...

     

TIPP: Es gibt einen Eintrag für Tabelle "i", aber es kann nicht referenziert werden   von diesem Teil der Abfrage.

Diese Art von Abfrage funktioniert in Firebird. Gibt es einen Weg, wie ich es schaffen könnte, indem ich nur eine Abfrage verwende? Ich möchte keine weitere gespeicherte Prozedur erstellen, die Elemente durchläuft und separate Aufrufe an compute_prices() vornimmt.

    
franbenz 08.02.2013, 12:37
quelle

3 Antworten

5

Im Allgemeinen können Sie bekannte Zeilentypen (auch Datensatztyp, komplexer Typ, zusammengesetzter Typ) mit dem einfache Syntax @Daniel geliefert :

%Vor%

Wenn Ihre Beschreibung jedoch korrekt ist ...

  

Der Parameter compute_prices gibt einen Datensatz zurück.

... es handelt sich um anonyme Datensätze. Postgres weiß nicht, wie man anonyme Datensätze erweitert, und löst verzweifelt eine AUSNAHME aus:

%Vor%

PostgreSQL 9.3

Dafür gibt es in Postgres 9.3 eine Lösung. LATERAL , wie in @a_horse in den Kommentaren :

%Vor%

Details im Handbuch .

PostgreSQL 9.2 und früher

Dinge werden haarig. Hier ist ein Workaround : Schreiben Sie eine Wrapper-Funktion, die Ihre anonymen Datensätze in einen bekannten Typ konvertiert:

%Vor%

Dann können Sie die einfache Lösung von @Daniel verwenden und einfach die Wrapper-Funktion einfügen:

%Vor%

PostgreSQL 8.3 und früher

PostgreSQL 8.3 hat gerade EOL erreicht und wird jetzt nicht unterstützt (Feb. 2013) .
Du solltest also besser upgraden, wenn es überhaupt möglich ist. Aber wenn du nicht kannst:

%Vor%

Funktioniert auch in späteren Versionen.

Die richtige Lösung wäre, Ihre Funktion compute_prices() zu reparieren, um zunächst einen bekannten Typ zurückzugeben. Funktionen, die SETOF record zurückgeben, sind im Allgemeinen ein PITA. Ich stoße nur die mit einer Fünf-Meter-Stange.

    
Erwin Brandstetter 08.02.2013, 18:53
quelle
3

Unter der Annahme, dass die compute_prices -Funktion immer einen Datensatz mit 3 Preisen zurückgibt, könnten Sie ihren Rückgabetyp auf TABLE (price numeric(15,2), discount numeric(5,2),taxes numeric(5,2)) setzen, und dann glaube ich, was Sie wollen, könnte wie folgt ausgedrückt werden:

%Vor%

Beachten Sie, dass es scheint, dass LEFT JOIN ON 1=1 sich nicht von einem unbeschränkten normalen JOIN (oder CROSS JOIN) unterscheidet, und ich interpretierte die Frage als nicht verwandt mit dem linken Join.

    
Daniel Vérité 08.02.2013 14:10
quelle
1

Ich glaube, Daniels Antwort wird auch funktionieren, aber ich habe es noch nicht versucht. Ich weiß, dass ich eine SP namens list_failed_jobs2 in einem Schema namens Protokollierung und eine Dummy-Tabelle namens Dual (wie in Oracle) und die folgende Anweisung funktioniert für mich:

%Vor%

Beachten Sie, dass der SP-Aufruf nicht ohne die Parens, die Korrelation (q) oder die ON-Klausel funktioniert. Mein SP gibt auch einen SETOF zurück.

Ich vermute also, dass so etwas für Sie funktioniert:

%Vor%

Ich hoffe, das hilft.

    
Brian.D.Myers 08.02.2013 18:00
quelle