Простой пример. Две таблицы. Продажа и товары/позиции в продаже.
В позициях - задано количество каждого товара и цена одной единицы. В продаже - указывается сумма по всем позициям total_price - SUM(quantity*item_price).
1. Создать продажу с нулевой общей суммой. Получить ID-продажи.
2. Используя ID продажи, вставить все позиции и посчитать сумму.
3. Выполнить обновление поля “общая сумма” в продаже.
⚠️ Не очень оптимально, появляется лишний update.
Можно пойти другим путем.
1. Сгенерировать ID-продажи (скорее всего, sequence).
2. Вставить позиции, посчитав при этом “общую сумму”.
3. Вставить саму продажу с ID и рассчитанной “общей суммой”.
❗️ Конечно, FK должен быть отложенным, иначе при попытке вставки в sale_detail возникнет ошибка (нет записи в sale).
Вполне вероятно, подобная техника может пригодиться при репликациях, загрузке данных и т.п. Когда непонятно, что идет вперед “курица или яйцо”.
Можете поделиться в комментариях кейсами, где вы использовали это свойство ограничений. Думаю, всем будет интересно.
#constraint
В позициях - задано количество каждого товара и цена одной единицы. В продаже - указывается сумма по всем позициям total_price - SUM(quantity*item_price).
create table sale(При создании продажи и детализации, можно поступить так:
sale_id number(30) primary key,
sale_date date default sysdate,
total_price number(20,2)
);
create table sale_detail(
sale_id number(30) not null,
item_id number(20) not null,
quantity number(10) not null,
item_price number(10,2) not null
constraint sale_detail_fk foreign key(sale_id) references sale(sale_id)
);
1. Создать продажу с нулевой общей суммой. Получить ID-продажи.
2. Используя ID продажи, вставить все позиции и посчитать сумму.
3. Выполнить обновление поля “общая сумма” в продаже.
⚠️ Не очень оптимально, появляется лишний update.
Можно пойти другим путем.
1. Сгенерировать ID-продажи (скорее всего, sequence).
2. Вставить позиции, посчитав при этом “общую сумму”.
3. Вставить саму продажу с ID и рассчитанной “общей суммой”.
❗️ Конечно, FK должен быть отложенным, иначе при попытке вставки в sale_detail возникнет ошибка (нет записи в sale).
Вполне вероятно, подобная техника может пригодиться при репликациях, загрузке данных и т.п. Когда непонятно, что идет вперед “курица или яйцо”.
Можете поделиться в комментариях кейсами, где вы использовали это свойство ограничений. Думаю, всем будет интересно.
#constraint
Задача: Есть две таблички. Связь Master(PK) - Detail(FK).
В Detail таблицу производится вставка. Такого ключа в Master-таблице нет.
Возникает ошибка.
Решение:
Изменить определение foreign key. C незамедлительной проверки (immediate, по умолчанию) на отложенную проверку (deferred).
На табличке, которая уже во всю используется такой фокус по удалению/созданию может не прокатить, зависит от вашей системы - 24/7.
Вероятно, придется использовать свойство ограничения Novalidate. Как-нибудь, расскажу о нем.
Возьмите себе на заметку, когда возникает задача типа “кто был первым курица или яйцо”, скорее всего, вам нужны отложенные проверки.
Если задачка понравилась - ставьте 👍
#решениезадачи #constraint
В Detail таблицу производится вставка. Такого ключа в Master-таблице нет.
Возникает ошибка.
Решение:
Изменить определение foreign key. C незамедлительной проверки (immediate, по умолчанию) на отложенную проверку (deferred).
alter table sale_detail drop constraint sale_detail_fk;
alter table sale_detail add constraint sale_detail_fk foreign key (sale_id)
references sale(sale_id)
deferrable initially deferred;
В таком случае, целостность данных будет проверяться только в момент commit.На табличке, которая уже во всю используется такой фокус по удалению/созданию может не прокатить, зависит от вашей системы - 24/7.
Вероятно, придется использовать свойство ограничения Novalidate. Как-нибудь, расскажу о нем.
Возьмите себе на заметку, когда возникает задача типа “кто был первым курица или яйцо”, скорее всего, вам нужны отложенные проверки.
Если задачка понравилась - ставьте 👍
#решениезадачи #constraint