Как принудительно установить значение столбца по умолчанию в PostgreSQL?

#postgresql #default-value #database-trigger

#postgresql #значение по умолчанию #database-триггер

Вопрос:

Есть ли какой-либо практический способ, кроме триггеров, игнорировать заданные запросом значения в пользу значений по умолчанию во время ВСТАВКИ / ОБНОВЛЕНИЯ?

Это поведение, которое я хочу заархивировать:

 CREATE TABLE foo (id serial, data text);

INSERT INTO foo (data) VALUES('bar1');
INSERT INTO foo (id, data) VALUES(50, 'bar2');
INSERT INTO foo (id, data) VALUES(-34, 'bar3');
INSERT INTO foo (id, data) VALUES(80.34, 'bar4');
INSERT INTO foo (id, data) VALUES('foo5', 'bar5');
INSERT INTO foo (data) VALUES('bar6');

UPDATE foo SET id=200, data='BARn' WHERE íd=6;

SELECT * FROM foo;

 ---- ------ 
| id | data |
 ---- ------ 
|  1 | bar1 |
|  2 | bar2 |
|  3 | bar3 |
|  4 | bar4 |
|  5 | bar5 |
|  6 | BARn |
 ---- ------ 
  

Спасибо!

Ответ №1:

Не совсем. Триггер — это путь сюда.

Ну, вы тоже могли бы использовать условное правило. Но я бы не стал.
С помощью ограничений проверки вы можете ограничивать только те значения или их комбинации, которые вам не нужны, но это вызовет исключение и вообще пропустит операцию.

Ответ №2:

Вы действительно не должны этого делать.

Вы должны программировать таким образом, чтобы ваш код не вел себя странно. После того, как вы вставите что-то в базу данных, эти данные должны быть вставлены или возникнет ошибка.

Вы можете обеспечить, чтобы это serial всегда было согласовано с помощью:

  • использование триггера after insert, который проверяет if NEW.id=curval('foo_id_seq') , и триггера after update, который проверяет if NEW.id=OLD.id , и выдает ошибку, если эта проверка завершается неудачей, но вы исключили триггеры по какой-то странной причине;
  • отключение доступа на запись к этой таблице для пользователей, отличных от суперпользователя, и создание функции для вставки данных:
    создать функцию insert_to_foo(текст) возвращает void как
    $$ вставить в foo(данные) значения ($1); $$
    language sql volatile security definer
    set search_path = public, pg_temp;

Комментарии:

1. В интересах других читателей, которые находят этот ответ полезным, функция называется currval , а не curval .

Ответ №3:

Существует способ отклонить определенные столбцы, отправленные пользователем, если это поможет. Следующим образом,

 revoke insert, update on table foo from public;
grant insert (data), update (data) on table foo to public;
  

Как показано, первое revoke значение должно быть во всей таблице. Если вы просто попытаетесь revoke insert (id) ..... , оно будет заменено существующими более полными разрешениями в таблице. Итак, он выполняет эти два указанных шага.

Имейте в виду, что отправка запрещенного столбца приведет к ошибке.