172 похожих чатов

Всем привет! Никак не могу написать констрнейнт таким образом, чтобы

он срабатывал перед вставкой записи в бд.

Я хочу, чтобы у меня констрейн не давал создавать дубликаты по двум конкретным полям и выбрасывал ошибку. Я использую CHECK constraint вместе с NOT VALID и вызываю функцию, которая проверяет моё условие unique_payment_title_constraint. Но когда я добавляю новую запись, она у меня сначала добавляется, а потом уже срабатывает функция на проверку, после добавления, которая выбрасывает исключение

```
ALTER TABLE payment_applications
ADD CONSTRAINT unique_name CHECK (
unique_payment_title_constraint(title, agent_nomenclature_id, contract_uuid)
) NOT VALID;
```

То есть, я внёс запись в таблицу, а потом функция выбросила исключение, потому что новая запись, которой раньше не было, теперь существует на момент проверки, после внесения уже

На триггерах это легко сделать, просто надо добавить триггер на BEFORE INSERT, и тогда оно будет работать как надо

Стоит ли эту проверку делать лучше на триггерах или на констрейнах?

8 ответов

12 просмотров

лучше через логику делать, а не через базу (субъективно)

Nikolay Underground
лучше через логику делать, а не через базу (субъек...

Констрейнты в БД, когда они применимы, почти всегда лучше проверок на клиенте БД, т.к. позволяют выполнить контроль целостности с минимальным оверхедом, в т.ч. не увеличивая времени блокировки записи. Чтобы получить те же гарантии со стороны клиента БД, вам придётся блокировать запись перед или в момент осуществления проверки и это, зачастую, будет отдельный запрос. С другой стороны, не всегда констрейнты удобны для анализа того, что не так, поэтому можно использовать двойную проверку: простую минимальную валидацию на клиенте БД без блокировки, но с отдачей развёрнутого ответа + констрейнт (при фейле которого возвращается системная ошибка, но вероятность этого небольшая)

1) unique лучшэ делать через unique или exclude. Многие проблемы решатся сами собой. 2) Мне сейчас лень проверять — но я бы скорее предположыл, что этот check не видит вообще записей, которые добавлены в том жэ запросе. Включая добавляемую. Как вы определили, что он выполняется "после"? Это точно? 3) В любом случае — обращаться к изменяемым частям БД в check крайне нерекомендуется. Если не получится через exclude — делайте на триггерах.

Radist
Констрейнты в БД, когда они применимы, почти всегд...

Я как раз имел ввиду, то что вы сказали "простую минимальную валидацию на клиенте БД без блокировки, но с отдачей развёрнутого ответа + констрейнт". Я не сторонник сложной логики, которую нужно добавдять в БД (тригеры и другие вещи, так как их сложно отслеживать)

Nikolay Underground
Я как раз имел ввиду, то что вы сказали "простую м...

С триггерами есть другая проблема: не каждый разработчик напишет триггер корректно, который будет гарантировать заявленную консистентность данных. Системные триггеры, реализующие тот же foreign key, писали профессионалы и тестировались всем сообществом.

Можно так alter table payment_applications add CONSTRAINT unique_name EXCLUDE (title WITH =, agent_nomenclature_id WITH =, contract_uuid with =); insert into payment_applications (title, agent_nomenclature_id, contract_uuid) values ('NAME1', 123::bigint, '123e4567-e89b-12d3-a456-426655440000'::uuid); insert into payment_applications (title, agent_nomenclature_id, contract_uuid) values ('NAME1', 123::bigint, '123e4567-e89b-12d3-a456-426655440000'::uuid); SQL Error [23P01]: ERROR: conflicting key value violates exclusion constraint "unique_name" Подробности: Key (title, agent_nomenclature_id, contract_uuid)=(NAME1, 123, 123e4567-e89b-12d3-a456-426655440000) conflicts with existing key (title, agent_nomenclature_id, contract_uuid)=(NAME1, 123, 123e4567-e89b-12d3-a456-426655440000).

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта