Frage

Ich brauche eine Postgres-Funktion eine virtuelle Tabelle zurückzukehren (wie in Oracle) mit benutzerdefinierten Inhalt. Die Tabelle würde 3 Spalten und eine unbekannte Anzahl von Zeilen.

Ich konnte einfach nicht die richtige Syntax im Internet finden.

Stell dir vor:

CREATE OR REPLACE FUNCTION "public"."storeopeninghours_tostring" (numeric)
  RETURNS setof record AS
DECLARE
  open_id ALIAS FOR $1;
  returnrecords setof record;
BEGIN
  insert into returnrecords('1', '2', '3');
  insert into returnrecords('3', '4', '5');
  insert into returnrecords('3', '4', '5');
  RETURN returnrecords;
END;

Wie das richtig geschrieben?

War es hilfreich?

Lösung

(Dies alles mit postgresql getestet 8.3.7-- Sie haben eine frühere Version? Nur bei der Nutzung von „ALIAS für $ 1“ suchen)

CREATE OR REPLACE FUNCTION storeopeninghours_tostring(numeric)
 RETURNS SETOF RECORD AS $$
DECLARE
 open_id ALIAS FOR $1;
 result RECORD;
BEGIN
 RETURN QUERY SELECT '1', '2', '3';
 RETURN QUERY SELECT '3', '4', '5';
 RETURN QUERY SELECT '3', '4', '5';
END
$$;

Wenn Sie einen Datensatz oder Zeile Variable zurück (anstelle eines Abfrageergebnis), verwenden Sie "NEXT RETURN" und nicht als "RETURN QUERY".

Um die Funktion Sie etwas tun müssen, aufrufen:

select * from storeopeninghours_tostring(1) f(a text, b text, c text);

Sie haben also zu definieren, was Sie die Ausgabezeile Schema der Funktion erwarten in der Abfrage sein. Um zu vermeiden, dass können Sie Ausgangsgrößen in der Funktionsdefinition angegeben werden:

CREATE OR REPLACE FUNCTION storeopeninghours_tostring(open_id numeric, a OUT text, b OUT text, c OUT text)
 RETURNS SETOF RECORD LANGUAGE 'plpgsql' STABLE STRICT AS $$
BEGIN
 RETURN QUERY SELECT '1'::text, '2'::text, '3'::text;
 RETURN QUERY SELECT '3'::text, '4'::text, '5'::text;
 RETURN QUERY SELECT '3'::text, '4'::text, '5'::text;
END
$$;

(nicht ganz sicher, warum die zusätzliche :: Text Abgüsse erforderlich ist ... '1' ist ein varchar standardmäßig vielleicht?)

Andere Tipps

Alle bisher vorhandenen Antworten sind veraltet oder ineffizient zu beginnen.

Angenommen, Sie drei integer Spalten zurückgeben möchten.

PL / pgSQL Funktion

Hier ist, wie Sie es tun mit modernen PL / pgSQL (PostgreSQL 8.4 oder höher):

CREATE OR REPLACE FUNCTION f_foo() -- (open_id numeric) -- parameter not used
  RETURNS TABLE (a int, b int, c int) AS
$func$
BEGIN
RETURN QUERY VALUES
  (1,2,3)
, (3,4,5)
, (3,4,5)
;
END
$func$  LANGUAGE plpgsql IMMUTABLE ROWS 3;

In Postgres 9.6 oder später können Sie auch hinzufügen PARALLEL SAFE .

Call:

SELECT * FROM f_foo();

Wichtige Punkte

  • Verwenden Sie RETURNS TABLE zu definieren, eine Ad-hoc Zeilentyp zurückzukehren.
    Oder RETURNS SETOF mytbl eine vordefinierte Zeilentyp zu verwenden.

  • Verwenden Sie RETURN QUERY zurückzukehren mehrere Zeilen mit einem Befehl.

  • Verwenden Sie einen VALUES Ausdruck mehrere Zeilen eingeben manuell. Dies ist Standard-SQL und hat rund immer .

  • Wenn Sie tatsächlich einen Parameter benötigen, einen Parameternamen (open_id numeric) anstelle von ALIAS, die abgeraten. Im Beispiel wurde der Parameter nicht verwendet und nur Rauschen ...

  • Keine Notwendigkeit für Doppel zitierte vollkommen legal Identifikatoren. Doppelte Anführungszeichen sind nur zu zwingen, sonst illegal Namen erforderlich (Groß- und Kleinschreibung, ungültige Zeichen oder reservierte Worte).

  • Funktion Volatilität kann IMMUTABLE werden, da das Ergebnis ändert sich nie.

  • ROWS 3 ist optional, aber da wir wissen , wie viele Zeilen zurückgegeben werden, können wir auch, es zu Postgres erklären. Kann die Abfrage Planern helfen, den besten Plan zu wählen.

Einfache SQL

Für einen einfachen Fall wie diesen, können Sie eine einfache SQL-Anweisung verwenden, statt:

VALUES (1,2,3), (3,4,5), (3,4,5)

Oder, wenn Sie wollen (oder müssen) bestimmte Spaltennamen und -typen definieren:

SELECT *
FROM  (
   VALUES (1::int, 2::int, 3::int)
        , (3, 4, 5)
        , (3, 4, 5)
   ) AS t(a, b, c);

SQL-Funktion

Sie können es in eine einfache SQL-Funktion rel="nofollow statt:

CREATE OR REPLACE FUNCTION f_foo()
   RETURNS TABLE (a int, b int, c int) AS
$func$
   VALUES (1, 2, 3)
        , (3, 4, 5)
        , (3, 4, 5);
$func$  LANGUAGE sql IMMUTABLE ROWS 3;

Ich benutze temporäre Tabellen ziemlich viel in meinen Funktionen. Sie benötigen einen Rückgabetyp auf der Datenbank erstellen und dann eine Variable dieses Typs zurück erstellen. Im Folgenden finden Sie Beispielcode, der genau das tut.

CREATE TYPE storeopeninghours_tostring_rs AS
(colone text,
 coltwo text,
 colthree text
);

CREATE OR REPLACE FUNCTION "public"."storeopeninghours_tostring" () RETURNS setof storeopeninghours_tostring_rs AS
$BODY$
DECLARE
  returnrec storeopeninghours_tostring_rs;
BEGIN
    BEGIN 
        CREATE TEMPORARY TABLE tmpopeninghours (
            colone text,
            coltwo text,
            colthree text
        );
    EXCEPTION WHEN OTHERS THEN
        TRUNCATE TABLE tmpopeninghours; -- TRUNCATE if the table already exists within the session.
    END;
    insert into tmpopeninghours VALUES ('1', '2', '3');
    insert into tmpopeninghours VALUES ('3', '4', '5');
    insert into tmpopeninghours VALUES ('3', '4', '5');

    FOR returnrec IN SELECT * FROM tmpopeninghours LOOP
        RETURN NEXT returnrec;
    END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;


select * from storeopeninghours_tostring()

Für diejenigen, die hier gelandet sind, die Suche nach dem MSSQL äquivalent eine temporäre Tabelle erstellen und seine Aufzeichnungen als Rückkehr Dumping aus ..., die nicht in PostgreSQL :( existiert -. Sie den Rückgabetyp definieren müssen Es gibt zwei Wege zum Zeitpunkt der Funktion Schöpfung dies zu tun, oder zum Zeitpunkt der Erstellung der Abfrage.

Siehe hier: http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions

CREATE OR REPLACE FUNCTION foo(open_id numeric, OUT p1 varchar, OUT p2 varchar, OUT p3 varchar) RETURNS SETOF RECORD AS $$
BEGIN
  p1 := '1'; p2 := '2'; p3 := '3';
  RETURN NEXT; 
  p1 := '3'; p2 := '4'; p3 := '5';
  RETURN NEXT; 
  p1 := '3'; p2 := '4'; p3 := '5';
  RETURN NEXT; 
  RETURN;
END;
$$ LANGUAGE plpgsql;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top