Я все еще работаю над этой базой данных для небольшого розничного магазина (сценарий, к счастью!) И в настоящее время пытаюсь решить эту проблему с помощью триггера.
Соответствующими объектами являются Клиент, Оплата и Заказ,Платеж является связующим звеном между двумя другими, поэтому один Клиент может совершать много платежей, а в одном заказе может быть много платежей (необычно, но все же возможно), и это нормально.
Триггер:
CREATE OR REPLACE TRIGGER Check_Payment_Status
BEFORE UPDATE OF Order_Status ON Customer_Order
for each row
DECLARE paymentStatus payment.payment_status%type;
BEGIN
select payment.payment_status into paymentStatus
from payment
where order_no = :new.order_no;
IF (paymentStatus ='Failed' OR paymentStatus IS NULL ) then
RAISE_APPLICATION_ERROR(-20103, 'The full payment has not been made so the order cannot be processed further until then.');
update customer_order set order_status='Delayed' where order_no= :new.order_no;
END IF;
IF (paymentStatus ='Successful' ) then
update payment set payment_date=SYSDATE where order_no= :new.order_no;
END IF;
END;
.
run
На данный момент работает нормально.Обычно, прежде чем заказ клиента может быть помечен как «Отправлено», статус платежа должен быть «Успешный».Если он имеет значение null или «Failed», триггер будет выглядеть как «о, нет, не!»(но в более формальных словах), который работает как задумано.Однако если применить бизнес-правило «заказ может иметь много платежей», триггер должен проверить все соответствующие платежи, где я получаю эту ошибку, поскольку оператор SELECT INTO
намеревается вернуть только одну строку.
Я немного читал о курсорах, но думаю, что здесь я зашёл слишком далеко - кто-нибудь может предложить какие-то решения, пожалуйста?