Пожалуйста, помогите мне вместо триггера рассчитать и обновить некоторые элементы! - PullRequest
0 голосов
/ 07 марта 2011

Мне нужно создать триггер (не процедуру) для обновления промежуточного итога, shipping_charge, tax и total_amount. По сути, все эти атрибуты взяты из таблицы заказов, и каждый из них включает в себя некоторые вычисления. промежуточный итог = Unit_Price * QTY, где Unit_Price берется из таблицы Product, а QTY - из таблицы Orderline. Проблема заключается в том, что когда таблица заказов была создана впервые, даты exp_ship и exp_receive не было, поэтому мне пришлось изменить таблицу заказов, чтобы добавить эти новые столбцы. Мне не разрешено менять старые данные. Итак, я создал копию таблицы «Заказы» для записей и работал над исходной таблицей заказов. Теперь каждый раз, когда делается новый заказ, мне нужно написать триггер, который вычислит промежуточную сумму, shipping_charge, tax и total_amt, и обновит эти поля в таблице заказов.

Я попробовал следующий код, но ошибок так много. Извините, но я пробую это в первый раз. Я все еще в процессе обучения. Я должен сделать это, создав представление и используя вместо него триггер вместо. То есть получить информацию из представления и обновить таблицу заказов.

DROP VIEW ORDERS_V;

CREATE VIEW ORDERS_V AS

SELECT * FROM ORDERS;

CREATE OR REPLACE TRIGGER update_orders

INSTEAD OF INSERT ON ORDERS_V

FOR EACH ROW

DECLARE 

SHIPPING_COST NUMBER(6,3);

BEGIN

SELECT UNIT_PRICE INTO UNIT_PRICE FROM PRODUCT;

SELECT QTY INTO QTY FROM ORDERLINE;

SELECT SHIPPING_METHOD INTO SHIPPING_METHOD FROM ORDERS;

SELECT SUBTOTAL INTO SUBTOTAL FROM ORDERS;

UPDATE ORDERS 

    SET SUBTOTAL = UNIT_PRICE * QTY;

    IF SHIPPING_METHOD = 'GROUND' THEN

        shipping_cost := .05;

    ELSIF SHIPPING_METHOD = '1 DAY' THEN

        shipping_cost :=   .15;

    ELSIF SHIPPING_METHOD = '2 DAY' THEN

        shipping_cost :=   .10; 
    ELSE 

    shipping_cost := 0;        

    END IF;

UPDATE ORDERS

    SET shipping_charge = SUBTOTAL * shipping_cost;

END;

/

1 Ответ

3 голосов
/ 07 марта 2011

В данный момент ваш триггер работает с целыми таблицами . Это явно не то, что вы хотите. Поэтому вам нужно добавить предложения WHERE в эти операторы, чтобы ограничить активность требуемыми строками. В триггерах мы используем нотацию :NEW., чтобы получить значения столбцов в таблице триггеров. Примерно так:

    SELECT UNIT_PRICE INTO :new.UNIT_PRICE FROM PRODUCT
    where product_id = :new.product_id;

    SELECT QTY INTO :new.QTY FROM ORDERLINE
    where order_id = :new.order_id;

Еще одно исправление синтаксиса: мы можем включить несколько столбцов в ОБНОВЛЕНИЕ. Это лучше, чем выдавать несколько заявлений.

UPDATE ORDERS 
SET :new.SUBTOTAL = ( :new.UNIT_PRICE * :new.QTY )
    , :new.shipping_charge = ( :new.SUBTOTAL * shipping_cost ) -- ??? see below
where order_id = :new.order_id
;

Я намеревался переписать весь ваш триггер. Однако ваша логика по-прежнему сбивает с толку (вы помните, я предложил вам уточнить некоторые вещи в моем ответе на ваш предыдущий вопрос ). Вещи, которые вам нужно исправить:

  1. Ваш триггер срабатывает на INSTEAD OF INSERT, но ваш код ОБНОВЛЯЕТ существующие записи в базовой таблице. А?

  2. Вы выбираете из ORDERLINE. Ожидаемая модель данных будет ЗАКАЗАТЬ, чтобы иметь одну или несколько ЛИНИЙ. Если это так, ваш код должен обрабатывать несколько строк для ORDERLINE (и я думаю, PRODUCT).

  3. Вы выбираете SUBTOTAL из базовой таблицы, хотя впоследствии вы перезаписываете значение. Затем вы используете SUBTOTAL в расчете: какое значение SUBTOTAL, по вашему мнению, вы используете?

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