Ich benutze Postgresql 9.1 mit Ubuntu 12.04.
Inspiriert von Craig Antwort auf meine Frage Verkettung von SETOF Typ oder SETOF Rekord Ich dachte , ich würde gut gehen mit der Verwendung return query
, setof record
und eine Reihe Generator in diese plpgsql Funktion:
create or replace function compute_all_pair_by_craig(id_obj bigint)
returns setof record as $$
begin
return query select o.id, generate_series(0,o.value) from m_obj as o;
end;
$$ language plpgsql;
Während der Ausführung erhalte ich den Fehler:
ERROR: set_valued function called in context that cannot accept a set
Was ist falsch ? Im Gegensatz zu Craig fordere ich die Funktion auf, zurückzukehren setof record
.
Ich kann etwas erreichen, das genau wie Craig create type pair_id_value as (idx bigint, value integer)
funktioniert , dh indem ich einen Typ definiere und meine plpgsql-Funktion a setof of pair_id_value
anstelle von a zurückgibt setof record
.
Aber selbst mit dieser funktionierenden Lösung verstehe ich immer noch nicht, warum select id, generate_series(0,13)
allein ein Ergebnis in zwei Spalten zurückgegeben wird ... und im Gegenteil, wenn die Funktion (gibt setof pair_id_value zurück) mit return query select id, generate_series(0,my_obj.value) from my_obj
ein Ergebnis in nur einer Spalte zurückgibt , wie das Feld aussieht diese (123123,0) (123123,1) (123123,2) (3 Zeilen), die offensichtlich Tupel sind.
Ist es ein Fall, in dem eine temporäre Tabelle erstellt werden muss / sollte?
quelle
BEGIN
und ein fehlendes nach demRETURN QUERY
. Nachdem ich diese Fehler korrigiert habe, bestätige ich den Fehler bei der Rücksendungrecord
. wird in Antwort erklären.Antworten:
Die Fehlermeldung ist nicht sehr hilfreich:
Wenn Sie die Abfrage jedoch umformulieren, um sie als ordnungsgemäße Set-Return-Funktion aufzurufen, sehen Sie das eigentliche Problem:
Wenn Sie
SETOF RECORD
ohneOUT
Parameterliste verwenden, müssen Sie die Ergebnisse in der aufrufenden Anweisung angeben, z.Aber es ist viel besser zu nutzen
RETURNS TABLE
oderOUT
Parameter. Mit der früheren Syntax wäre Ihre Funktion:Dies kann im SELECT-Listenkontext aufgerufen werden und kann verwendet werden, ohne explizit einen Typ zu erstellen oder die Ergebnisstruktur am Aufrufstandort anzugeben.
In der zweiten Hälfte der Frage werden im ersten Fall zwei separate Spalten in einer SELECT-Liste angegeben, während in der zweiten ein einzelner Verbund zurückgegeben wird. Es hängt eigentlich nicht damit zusammen, wie Sie das Ergebnis zurückgeben, sondern wie Sie die Funktion aufrufen. Wenn wir die Beispielfunktion erstellen:
Sie werden den Unterschied zwischen den beiden Möglichkeiten zum Aufrufen einer Set-Return-Funktion sehen - in der
SELECT
Liste eine PostgreSQL-spezifische Nicht-Standard-Erweiterung mit eigenartigem Verhalten:oder als Tabelle auf die üblichere Weise:
quelle
returns table
.