#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, который проверяет ifNEW.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) .....
, оно будет заменено существующими более полными разрешениями в таблице. Итак, он выполняет эти два указанных шага.
Имейте в виду, что отправка запрещенного столбца приведет к ошибке.