to niemożliwe z prostym DEFAULT
wartości, gdyż the manual clearly states:
Wartość ta jest dowolna zmienna wolne ekspresji (podzapytania i odsyłacze do innych kolumn w bieżącej tablicy, nie są dozwolone).
można użyć trigger zamiast:
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();
Aby to bardziej skuteczne używam WHEN
klauzuli (dostępna od PostgreSQL 9.0) z definicji wyzwalacza. W ten sposób funkcja wyzwalacza jest wykonywana tylko wtedy, gdy jest rzeczywiście przydatna. Zakładam, że możemy pozwolić, aby b IS NULL
przesuwał się, jeśli a IS NULL
.
Działa w podobnym, ale subtelnie innym mody z wartości DEFAULT
.
Przy wartości domyślnej można jawnie wstawić NULL
, aby anulować wartość domyślną. To niemożliwe tutaj, NULL
w b
jest zastąpione wartością pochodzącą z a
.
Dzięki za dopracowaną i zwięzłą odpowiedź – mosid