uns folgende Dinge in PostgreSQL Lassen Sie haben:Return NULL anstelle von Composite-Wert von PostgreSQL Funktion
CREATE TYPE struct AS (x INT, y INT);
CREATE TABLE tbl (a INT, b struct);
CREATE FUNCTION find_tbl_entry(clear BOOL) RETURNS tbl AS $$
DECLARE k tbl;
BEGIN
IF clear THEN
k.b := NULL;
END IF;
RETURN k;
END;
$$ LANGUAGE plpgsql;
Das heißt, wir haben eine Funktion einen Wert des zusammengesetzten Typ Rückkehr tbl
, was wiederum ein Attribut hat b
des zusammengesetzten Typs struct
als eines seiner Attribute. (Das ursprüngliche Problem ist interessanter - eine Übersetzungsfunktion eine Zeile mit einigen Attributen übersetzt entsprechend zurückkehrt;. Das Problem läuft darauf hinaus, den präsentierten Code nach unten, obwohl)
SELECT find_tbl_entry(FALSE)
Ergebnisse in (,(,))
, dh NULL als Wert a
und eine leere Struktur (ein Paar von NULL und NULL) als der Wert von b
, die etwas erwartet wird. Jetzt
, auch SELECT find_tbl_entry(TRUE)
Ergebnisse in (,(,))
, das heißt, auch wenn das b
Attribut explizit auf NULL
gesetzt ist, ist das Ergebnis nicht NULL
, aber es ist immer noch die leere Struktur.
Was kann ich tun, damit die Funktion find_tbl_entry
NULL
im Attribut b
zurückgibt?
EDIT: Wie sich herausstellt, das Merkwürdige ist, die Zuordnung k.b := NULL
. Wenn die Funktion erweitert wird:
k.b := NULL;
RAISE NOTICE '%', k.b IS DISTINCT FROM NULL;
es emittiert "HINWEIS: t". Daher scheint es, dass das Zuweisen von NULL
zu einem zusammengesetzten Wert tatsächlich einem Verbund mit allen Attributen NULL
zuweist. Das ist ziemlich merkwürdig, wenn man bedenkt, dass NULL
Werte von (NULL,NULL)
unterscheidbar sind, wenn sie in einer Tabelle gespeichert sind (UPDATE tbl SET b = NULL
ergibt b IS NOT DISTINCT FROM NULL
Halten für jede Reihe; andererseits ist UPDATE tbl SET b = (NULL,NULL)
false
für diesen Test).
Kennen Sie zufällig eine Variante der ersten Option, die gegen Modifikationen von 'tbl'-Spalten defensiv wäre?Ich meine, wenn eine zusätzliche Spalte zu "tbl" hinzugefügt wird, wäre es schön, wenn die Funktion nicht bricht - besonders wenn das Problem nur zur Laufzeit auftritt, wenn die Funktion tatsächlich aufgerufen wird. –
@ OndřejBouda Bearbeitet –
Danke für die Bearbeitung, der Code scheint jedoch nicht korrekt zu sein ('RETURN' sollte keinen Parameter in einer Funktion haben, die eine Tabelle zurückgibt), und spricht von Typen, gibt es eine Tabelle und nicht eine einzelne Zeile zurück. Ich verstehe den Punkt jedoch. Definieren Sie einfach den Rückgabetyp als neuen zusammengesetzten Typ "t" und geben Sie ihn unter Verwendung des vorgeschlagenen Konstrukts return (1, nullif (s, (null, null) :: struct)) zurück; 'löst das Problem. Könnten Sie bitte die bearbeitete Version korrigieren, damit ich die Antwort akzeptieren kann? –