Zuweisung von record-Elementen zu einer Variablen

Fragen und Probleme zu PL/pgSQL.
Antworten
surveyor_wb
Neuer Benutzer
Beiträge: 4
Registriert: So 6. Sep 2015, 12:23

Zuweisung von record-Elementen zu einer Variablen

Beitrag von surveyor_wb » Mo 9. Mai 2016, 11:10

Hallo,

ich stecke seit einiger Zeit bei folgender Problematik fest:
Ausgangszustand: Aufruf einer Funktion durch eine Anweisung, in der eine Tabelle mit zwei Spalten zurückgegeben werden soll, also z.B aufzurufende Funktion.

Code: Alles auswählen

CREATE OR REPLACE FUNCTION funktion_1(
    IN my1_text text,
    IN my2_text text,
    IN geom geometry)
  RETURNS TABLE(result text, geomet geometry) AS
  --Code zum Erzeugen der Tabellenwerte
Anschließend aufrufende Anweisung

Code: Alles auswählen

rec:= (SELECT ROW(result, geomet) FROM funktion_1(my1_text, my2_text, geom));
Die so aufgerufene Funktion gibt einen record zurück, der auch den korrekten Inhalt der Zeile - durch Komma getrennt- enthält.

Wie weise ich jetzt den jeweiligen Spalteninhalt des so erzeugten records einer Variablen zu, also z.B.:

Code: Alles auswählen

var_1:= rec.result; 
var_2:= rec.geomet;
Diese Zuweisung funktioniert nicht. Fehlermeldung: record rec hat kein Feld result bzw.record rec hat kein Feld geomet.

Wer kann helfen? Ich habe immer mit irgendwelchen workarounds das Problem umgangen. Ich würde jetzt aber gern die Ursache und die richtige Lösung wissen. Vor allen Dingen wundert mich, dass trotz dauernder Wiederholung der Benennung der Spalten diese nicht als solche angesprochen werden können.

Vielen Dank im Voraus

Theo

castorp
Erfahrener Benutzer
Beiträge: 1177
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: Zuweisung von record-Elementen zu einer Variablen

Beitrag von castorp » Mo 9. Mai 2016, 11:32

Nimm ein select into:

Code: Alles auswählen

select result, geomet
   into var_1, var_2
FROM funktion_1(my1_text, my2_text, geom);
http://www.postgresql.org/docs/current/ ... SQL-ONEROW

Das funktioniert aber nur wenn die Funktion auch nur genau einen Datensatz zurück liefert (warum sie dann aber als "returns table()" definiert wurde verstehe ich nicht).

Wenn Du die Felder explizit verwenden willst musst Du in der aufrufenden Funktion eine typisiert Variable verwenden, nicht einfach nur "RECORD". Dazu musst Du einen entsprechenden Datentyp definieren:

Code: Alles auswählen

create type funk_type as (result text, geomet geometry);
Die Funktion muss dann entsprechend den Type des Rückgabewerts definieren:

Code: Alles auswählen

CREATE OR REPLACE FUNCTION funktion_1(
    IN my1_text text,
    IN my2_text text,
    IN geom geometry)
  RETURNS setof funk_type AS
  ...
Wenn die Funktion tatsächlich nur einen Wert zurück liefert, dann eher "RETURNS funk_type" und nicht "RETURNS SETOF ..."

Und dort wo Du die Funktion verwendest, dann entsprechend:

Code: Alles auswählen

declare
    rec funk_type;
    var_1 text;
    var_2 geometry;
begin
   ...
   var_1 := rec.result;
   var_2 := rec.geomet;
   
   ...
end;
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

surveyor_wb
Neuer Benutzer
Beiträge: 4
Registriert: So 6. Sep 2015, 12:23

Re: Zuweisung von record-Elementen zu einer Variablen

Beitrag von surveyor_wb » Mo 9. Mai 2016, 12:33

Vielen Dank für die sehr schnelle Antwort.
Meine Funktionsinhalte und Aufrufe sind deutlich komplexer, daher returns table. Ich habe es nur auf eine einfache Form heruntergebrochen.
Bezüglich der selbst definierten Typen habe ich das bisher als einen meiner workarounds angesehen.

Meine Frage zielt vom Kern her auch darauf, dass wenn man die Möglichkeit schafft, in einer aufgerufenen Funktion einen definierten Typ zurückzugeben (hier z.B. table oder Zeilen eines tables), warum man diesen Typ in der aufrufenden Funktion nicht auf einfache Art und Weise auch ansprechen bzw. einer Variablen, die auswertbar ist, zuweisen kann. Das ist für mich schwer nachvollziehbar.
Daher war ich der Meinung, dass es dafür bestimmt eine einfache Variante gibt, die ich bisher nicht kenne.

Gruß
Theo

castorp
Erfahrener Benutzer
Beiträge: 1177
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: Zuweisung von record-Elementen zu einer Variablen

Beitrag von castorp » Mo 9. Mai 2016, 12:47

surveyor_wb hat geschrieben:Meine Frage zielt vom Kern her auch darauf, dass wenn man die Möglichkeit schafft, in einer aufgerufenen Funktion einen definierten Typ zurückzugeben (hier z.B. table oder Zeilen eines tables)
"returns table" gibt eben keinen definierten Typ zurück. Das wird eben nur über "returns setof xxxx" erreicht.
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

Antworten