Как правило, мне было бы немного не по себе от вычисляемых столбцов в таблице, таких как строка или счет-фактура.Часто возникают проблемы с целостностью данных, когда вычисляемый результат не равен сохраненному результату.
Вместо того, чтобы иметь столбец LINE.LinePrice, у вас может быть запрос, который вычислит LinePrice по требованию:
SELECT l.LineID, l.LineQty, l.LineQty * s.Price AS LinePrice, l.InvoiceID, l.ServiceID
FROM LINE l, SERVICE s
WHERE s.ServiceID = l.ServiceID
Как и в случае с INVOICE.InvoiceTotal, вы можете сделать запрос примерно так:
SELECT i.InvoiceID, SUM(x.LinePrice) AS InvoiceTotal
FROM INVOICE i
,(SELECT l.InvoiceID, l.LineQty * s.Price AS LinePrice
FROM LINE l, SERVICE s
WHERE s.ServiceID = l.ServiceID) x
WHERE i.InvoiceID = x.InvoiceID
GROUP BY i.InvoiceID
Если вы пойдете по этому маршруту, то вам также придется подумать о том, что происходит, когда цена услуги меняется,Если вы печатаете старые счета-фактуры, собираетесь ли вы рассчитывать новые итоги или вы хотите использовать исторические значения для вычисления того, каким был счет-фактура в прошлом?Вероятно, последнее, поэтому изменения в таблице Service должны быть эффективными с датой, имеющей дату как часть ключа.Затем вы можете отслеживать исторические цены.
Но я также понимаю, что нужно иметь фиксированное статическое значение, если счет выставлен (обычно это архивный документ).Если вы хотите пройти маршрут триггера, триггер может выглядеть примерно так (у меня нет доступного экземпляра Oracle, поэтому вам нужно будет проверить синтаксис):
CREATE OR REPLACE TRIGGER line_insert
BEFORE INSERT ON line
FOR EACH ROW
BEGIN
SELECT :new.LineQty * Price
INTO :new.LinePrice
FROM Service
WHERE serviceID = :new.ServiceID;
END;
Это просто попыткасделайте LinePrice на Вставке.Вам также необходимо увеличить InvoiceTotal.И вам нужно будет следить за сценариями UPDATE (вычесть: старая сумма и добавить: новая сумма) и DELETE (вычесть: старая сумма).