2017-05-15 1 views
1

zurückgeben Ich versuche, mehrere Werte in plpgsql mit einer sehr vereinfachten Testfunktion zurückzugeben. Die Testfunktion nimmt eine Ganzzahl als Eingabe und soll zurückkehren, wenn sie positiv, negativ und Null ist. Ich habe ein Beispiel gesehen, aber sie sind alle kompliziert und gehen mir über den Kopf. HierEinen Datensatz von der Funktion

ist, was ich versucht:

create or replace function test(v integer) 
returns record as $$ 

BEGIN 

    IF v > 0 
     THEN return true as positive, false as negative, false as zero; 
    ELSEIF v < 0 
     THEN return false as positive, true as negative, false as zero; 
    ELSE 
     return false as positive, false as negative, true as zero; 
    END IF; 

END; 
$$ LANGUAGE plpgsql; 

auch versucht, diese

create or replace function test(v integer) 
returns record as $$ 

DECLARE 
    result record; 

BEGIN 

    IF v > 0 
     THEN 
      result.positive = true; 
      result.negative = false; 
      result.zero = false; 

    ELSEIF v < 0 
     THEN 
      result.positive = false; 
      result.negative = true; 
      result.zero = false; 
    ELSE 
      result.positive = false; 
      result.negative = false; 
      result.zero = true; 
    return result; 
    END IF; 

END; 
$$ LANGUAGE plpgsql; 

auch dieses:

IF v > 0 
    THEN 
     SELECT true, false, false into 
     result.positive, result.negative, result.zero; 

ELSEIF v < 0 
    THEN 
     SELECT false, true, false into 
     result.positive, result.negative, result.zero; 
ELSE 
     SELECT false, false, true into 
     result.positive, result.negative, result.zero; 
return result; 
END IF; 

Antwort

1

I w wie folgt Ould das Problem lösen:

CREATE TYPE sign AS ENUM ('negative', 'zero', 'positive'); 

CREATE FUNCTION test(integer) RETURNS sign 
    LANGUAGE sql IMMUTABLE STRICT AS 
$$SELECT CASE 
      WHEN $1 < 0 
      THEN 'negative' 
      WHEN $1 > 0 
      THEN 'positive' 
      ELSE 'zero' 
     END::sign$$; 

Wenn Sie eine record zurückkehren möchten, wie Sie in Ihren Beispielen tun, werden Sie den ROW() Konstruktor zum Erstellen eines einzigen zusammengesetzten Wert aus den drei booleans verwenden müssen:

RETURN ROW(true, false, false); 

Aber diese Lösung hat auch ihre Nachteile: Sie können die einzelnen Felder des zusammengesetzten Typs in SQL nicht zugreifen können, weil PostgreSQL kennt nicht die Felder zur Analysezeit:

test=> SELECT test(42); 
┌─────────┐ 
│ test │ 
├─────────┤ 
│ (t,f,f) │ 
└─────────┘ 
(1 row) 

test=> SELECT (test(42)).*; 
ERROR: record type has not been registered 

test=> SELECT * FROM test(42); 
ERROR: a column definition list is required for functions returning "record" 
LINE 1: SELECT * FROM test(42); 
        ^

Sie müssten die Datensatzdefinition in der Abfrage angeben:

test=> SELECT positive FROM test(42) test(positive boolean, negative boolean, zero boolean); 
┌──────────┐ 
│ positive │ 
├──────────┤ 
│ t  │ 
└──────────┘ 
(1 row) 

Aber diese Art von trotzt Ihr Ziel von variablen Datensätzen. Aus diesem Grund sind solche Funktionen weniger nützlich als die Antwort, auf die Sie sich beziehen.

+0

Die Antwort hier: http://StackOverflow.com/A/6085167/4299560 sagt RECORD Typ zu verwenden. Deshalb hat meine Frage spezifisch danach gefragt. Es scheint viel praktischer zu sein, als Typen jedes Mal zu erstellen, wenn ich ein benutzerdefiniertes Ergebnis benötige. – Ced

+0

Wahr. Ich habe die Antwort erweitert, um speziell die "Aufzeichnung" abzudecken, damit Sie Ihre Funktionen ausführen können. –

1

Dies wird einen Datensatz zurückgeben, so dass das Ergebnis (wahr, falsch, falsch) sein wird.

CREATE OR REPLACE FUNCTION test(v integer) 
    RETURNS record AS $$ 

DECLARE 
    result record; 

BEGIN 
     SELECT true , false , false into result; 
return result; 

END; 

Das Problem ist, dass das Ergebnis nicht gestattet, so dass Sie diese haben (true, false, false) und Sie separat jeden Wert zu erhalten. Um dies zu tun, können Sie dies tun:

select a, b, c from test(1) AS (a BOOL, b bool, c bool); 
Verwandte Themen