Применение бизнес-правил в Oracle - PullRequest
0 голосов
/ 24 июля 2010

У меня есть стол под названием Книга. Эта таблица имеет 3 столбца, а именно идентификатор, цену и скидку. Если цена больше 200, тогда скидка должна составлять 20%. При вставке данных в таблицу Book значение скидки должно обновляться на основе значения цены. Как это можно сделать, когда данные вставляются или обновляются в таблице Book?

Пожалуйста, предоставьте все возможные решения. Я не хочу выполнять хранимую процедуру. Предположим, когда пользователь вставляет / обновляет данные в таблице Book, чтобы он не выполнял функцию или процедуру.

Пожалуйста, предоставьте решение.

Ответы [ 3 ]

2 голосов
/ 24 июля 2010

Если вы не хотите использовать хранимую процедуру, тогда единственным другим вариантом является триггер.

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 не предоставляет механизм для прикрепления конкретного сообщения об ошибке к нашему проверочному ограничению.Возможность вызывать контекстно-специфическое исключение с помощью значимого сообщения является одним из преимуществ хранимых процедур.

1 голос
/ 25 июля 2010

Без использования каких-либо хранимых процедур:

ALTER TABLE "Book" ADD (
  CONSTRAINT discount_check
  CHECK (price < 200 OR discount = 0.2)
);

Таким образом, никто не сможет вставить или обновить Книгу, если они не введут соответствующие значения для цены и скидки. *

* (для пуленепробиваемости вы бы добавили ограничения NOT NULL и к этим столбцам)

0 голосов
/ 26 июля 2010

Если скидка всегда является функцией цены, я бы посоветовал сделать ее рассчитанным столбцом в представлении. Для таблицы Books со столбцами id и price создайте вид, подобный этому:

CREATE VIEW books_view AS (
  SELECT
    id,
    price,
    CASE WHEN price > 200 THEN 0.20 ELSE 0 END discount
  FROM books
  );

Таким образом, пользователь не может установить скидку на неправильное значение. При использовании триггерных решений скидка может быть правильно установлена ​​при вставке, но затем ее можно изменить в последующих обновлениях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...