Isso não é possível com um simples
DEFAULT
valor, como o manual indica claramente:
O valor é qualquer expressão livre de variáveis (subconsultas e referências cruzadas a outras colunas na tabela atual não são permitidas).
Você pode usar um gatilho em vez de:
CREATE OR REPLACE FUNCTION trg_foo_b_default()
RETURNS trigger
LANGUAGE plpgsql 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, consider a lookup table:
SELECT INTO NEW.b t.b
FROM def_tbl t
WHERE t.a = NEW.a;
*/
RETURN NEW;
END
$func$;
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();
Para torná-lo mais eficiente, use um
WHEN
cláusula na definição do trigger (disponível desde o Postgres 9.0):Desta forma a função trigger só é executada, quando for realmente útil. (Assumindo que podemos deixar b IS NULL
slide se a IS NULL
.) Funciona de forma semelhante, mas sutilmente diferente moda de um
DEFAULT
value.Com um valor padrão, você pode inserir explicitamente
NULL
para anular o padrão. Isso não é possível aqui, NULL
em b
é substituído pelo valor derivado de a
.