Редактировать : Первоначально удалили это, когда я поняла, что этого недостаточно, если задействовано более одного сеанса.Отмена удаления, чтобы показать пример решения, которое не отображает проблему «таблицы мутаций».Вам придется заблокировать таблицу, чтобы сначала на нее мог влиять только один сеанс.
Вы можете сделать это с помощью триггера AFTER STATEMENT
.Это выполняется один раз в insert
, update
или delete
после завершения всего оператора.Это немного неаккуратно, потому что он проверяет все строки в таблице, даже те, которые не были затронуты, но для ваших целей это, вероятно, достаточно хорошо.
create or replace trigger trig1
after insert or update on ownership
declare
l_count number;
begin
select count(*) into l_count from (
select buildingid, sum(ownershipstake)
from ownership
group by buildingid
having sum(ownershipstake) > 100
);
if l_count > 0 then
raise_application_error( -20001, 'Totals cant be over 100' );
end if;
end;
/
insert into ownership values ( 1, 1, 99 );
insert into ownership values ( 2, 1, 2 );
Error starting at line : 24 in command -
insert into ownership values ( 2, 1, 2 )
Error report -
ORA-20001: Totals cant be over 100
Как я уже сказал, это проверяет всю таблицу , хотя я только вставил строку, которая затронула 1 здание здесь.Поэтому, если у вас миллион зданий, он без необходимости проверяет 999 999 строк и может оказать значительное влияние на производительность.
Улучшенный способ сделать это - составной триггер, где в момент времени before each row
вы бы записалиидентификатор здания изменяемой строки.Затем в момент времени after statement
вы будете проверять только те здания, которые были изменены.