Ответ 1
Это невозможно с простым значением DEFAULT
, поскольку в руководстве четко указано:
Значение представляет собой любое выражение без переменных (подзапросы и перекрестные ссылки на другие столбцы в текущей таблице не разрешены).
Вместо этого можно использовать триггер:
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();
Чтобы сделать это более эффективным, я использую предложение WHEN
(доступно с Postgres 9.0) с определением триггера. Таким образом, триггерная функция выполняется только тогда, когда она действительно полезна. Я предполагаю здесь, мы можем позволить b IS NULL
скользить, если a IS NULL
.
Работает с аналогичным, но тонко отличающимся способом от значения DEFAULT
.
Со значением по умолчанию вы можете явно вставить NULL
, чтобы отменить значение по умолчанию. Это невозможно сделать, NULL
в b
заменяется значением, полученным из a
.