Antwort

22

Dies ist nicht möglich mit einem einfachen DEFAULT Wert, wie the manual clearly states:

Der Wert ist eine Variable freier Ausdruck (Unterabfragen und Querverweise zu anderen Spalten in der aktuellen Tabelle ist nicht zulässig).

Sie könnten ein trigger statt:

CREATE OR REPLACE FUNCTION trg_foo_b_default() 
    RETURNS trigger AS 
$func$ 
BEGIN 

-- For just a few constant options, CASE does the job: 
NEW.b := 
    CASE NEW.a 
    WHEN 'peter' THEN 'doctor' 
    WHEN 'weirdo' THEN 'shrink' 
    WHEN 'django' THEN 'undertaker' 
    ELSE NULL 
    END; 

/* -- For more, or dynamic options, you could use a lookup table: 
SELECT INTO NEW.b t.b 
FROM def_tbl t 
WHERE t.a = NEW.a; 
*/ 

RETURN NEW; 

END 
$func$ LANGUAGE plpgsql; 

CREATE TRIGGER b_default 
BEFORE INSERT ON foo 
FOR EACH ROW 
WHEN (NEW.b IS NULL AND NEW.a IS NOT NULL) 
EXECUTE PROCEDURE trg_foo_b_default(); 

Um dies effektiver Ich benutze eine WHEN Klausel (verfügbar seit Postgres 9.0) mit der Trigger-Definition. Auf diese Weise wird die Triggerfunktion nur ausgeführt, wenn sie tatsächlich nützlich ist. Ich gehe davon aus, dass wir b IS NULL schieben können, wenn a IS NULL.

Funktioniert in einer ähnlichen, aber subtil verschiedenen Mode von einem DEFAULT Wert.
Mit einem Standardwert können Sie NULL explizit einfügen, um den Standardwert zu überschreiben. Das ist hier nicht möglich, NULL in b wird durch den von a abgeleiteten Wert ersetzt.

+0

Danke für ausgearbeitete und knappe Antwort – mosid