Если вы не хотите использовать хранимую процедуру, тогда единственным другим вариантом является триггер.
create or replace trigger book_discount_rule
before insert, update on BOOK
for each row
begin
if :new.price > 200
then
:new.discount := 20;
else
:new.discount := 0;
end if;
end;
Лично мне не нравится это решение именно потому, что триггеры невидимы.То есть, если пользователь запускает этот оператор вставки ...
insert into book
values (book_id_seq.nextval, 250, 30)
/
... они могут быть озадачены тем, почему сохраненный DISCOUNT отличается от значения, которое он представил.Я бы предпочел использовать хранимую процедуру для обеспечения соблюдения бизнес-правил.
В любом случае, в реальной жизни я бы предпочел, чтобы правила реализовывались через API, а не жестко кодировали значения.Но это дело вкуса.
Как указывает Джеффри, неплохо бы создать резервную копию триггера (или процедуры) с проверочным ограничением на столе, чтобы гарантировать, что DISCOUNT подходит дляЦена.
alter table book
add constraint book_discount_ck
check ((price > 200 and discount = 20) or discount = 0)
/
Чтобы применить ограничение без хранимой процедуры или триггера o, пользователь должен знать бизнес-правило.К сожалению, Oracle не предоставляет механизм для прикрепления конкретного сообщения об ошибке к нашему проверочному ограничению.Возможность вызывать контекстно-специфическое исключение с помощью значимого сообщения является одним из преимуществ хранимых процедур.