risposta

22

Questo è impossibile con un semplice valore DEFAULT, come the manual clearly states:

Il valore è qualsiasi espressione priva di variabile (sottoquery e riferimenti incrociati ad altre colonne della tabella corrente non sono ammessi).

si potrebbe usare un trigger invece:

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(); 

per renderlo più efficace uso una clausola di WHEN (disponibile dal Postgres 9.0) con la definizione di trigger. In questo modo la funzione trigger viene eseguita solo quando è effettivamente utile. Presumo qui, possiamo lasciare la diapositiva b IS NULL se a IS NULL.

Funziona in modo simile, ma sottilmente diverso da un valore DEFAULT.
Con un valore predefinito, è possibile inserire esplicitamente NULL per annullare l'impostazione predefinita. Non è possibile qui, NULL in b viene sostituito con il valore derivato da a.

+0

Grazie per la risposta elaborata e concisa – mosid