колонка не допускается здесь - PullRequest
0 голосов
/ 12 апреля 2011
CREATE OR REPLACE TRIGGER update_QOH
BEFORE INSERT ON ORDERLINE
FOR EACH ROW
DECLARE
    QOH_PRODUCT PRODUCT.QOH%TYPE;
    ORD_NO ORDERS.ORDER_NO%TYPE;
BEGIN
    SELECT QOH INTO QOH_PRODUCT FROM PRODUCT
    WHERE :old.product_no = :new.product_no;

    SELECT ORDER_NO INTO ORD_NO FROM ORDERLINE
    WHERE :old.order_no = :new.order_no;

    IF (:new.QTY <= QOH_PRODUCT) THEN   
        UPDATE PRODUCT SET QOH = QOH_PRODUCT - :new.QTY;
    ELSE
        send_email(ord_no, 'Backorder');

        INSERT INTO BACKORDER
        VALUES (backorder_no_seq.NEXTVAL, :new.product_no, :new.qty, SYSDATE);

        INSERT INTO PRODVENDOR
        VALUES (po_no_seq.NEXTVAL, vendor_no, :new.product_no, vend_qty,
            shipping_method, SYSDATE, NULL, NULL, NULL);
    END IF; 
END;
/
-------------------------------------------------------------------------------
Error(13,3): PL/SQL: SQL Statement ignored

Error(13,91): PL/SQL: ORA-00984: column not allowed here
--------------------------------------------------------------------------------

Таблица продуктов (P_no, QOH и т. Д.)

Таблица строки заказа (OL_no, QTY и т. Д.)

Таблица невыполненных заказов (B_no, B_QTY и т. Д.)

Таблица поставщиков (V_no и т. Д.)

Мне нужно убедиться, что когда покупатель покупает продукт, в таблице продуктов достаточно QOH, если он есть, QOH в продукте должен быть уменьшен (обновлен). Если нет, отправьте электронное письмо клиенту, обновите таблицу отставания, и продукт должен быть заказан у продавца.

Ответы [ 3 ]

2 голосов
/ 12 апреля 2011

Во-первых, рассмотрите возможность вставки вставки в процедуру вместо триггера. (И, возможно, более полезное имя). Вставка или обновление других таблиц может привести к путанице, если позже они получат свои собственные триггеры, и трудно отслеживать, что и когда происходит.

Во-вторых, похоже, что он не очень хорошо справляется с одновременными вставками - две новые вставки ORDERLINE для одного и того же продукта одновременно будут пытаться обновить QOH продукта с вероятными неожиданными или нежелательными результатами - QOH может стать отрицательным , например. Вы также можете получить несколько заказов поставщику; каждая строка заказа, которая запрашивает товар, отсутствующий на складе, будет делать новый заказ поставщику, даже если количество каждой строки заказа равно 1 и вы заказываете 100 у поставщика за раз.

В-третьих, различные ошибки кода; Я начну с нескольких более очевидных:

a) Вы выбираете из PRODUCT и ORDERLINE с WHERE :old.product_no = :new.product_no. Я не уверен, что :OLD даже установлен в триггере перед вставкой, но если это так, он будет таким же, как :NEW или ноль, так что вы, возможно, получите ошибки ORA-02112 или ORA-01403 так как он найдет все строки или, возможно, ни одной.

b) Ваш выбор из ORDERLINE не вернет ни одной строки в первой строке заказа и нескольких строк начиная с третьей и так далее, так что вы снова получите ошибки ORA-01403 и ORA-02112. Но это бессмысленно, поскольку вы просто выбираете значение, к которому обращаетесь. Вы можете просто использовать значение :NEW в сообщении электронной почты.

c) В вашем обновлении PRODUCT нет предложения WHERE, поэтому все значения QOH будут обновлены.

CREATE OR REPLACE TRIGGER update_QOH
BEFORE INSERT ON ORDERLINE
FOR EACH ROW
DECLARE
    QOH_PRODUCT PRODUCT.QOH%TYPE;
BEGIN
    SELECT QOH INTO QOH_PRODUCT FROM PRODUCT
    WHERE product_no = :new.product_no;

    IF (:new.QTY <= QOH_PRODUCT) THEN   
        UPDATE PRODUCT SET QOH = QOH_PRODUCT - :new.QTY;
        WHERE product_no = :new.product_no;
    ELSE
        send_email(:new.order_no, 'Backorder');

        INSERT INTO BACKORDER
        VALUES (backorder_no_seq.NEXTVAL, :new.product_no, :new.qty, SYSDATE);

        INSERT INTO PRODVENDOR
        VALUES (po_no_seq.NEXTVAL, vendor_no, :new.product_no, vend_qty,
            shipping_method, SYSDATE, NULL, NULL, NULL);
    END IF; 
END;
/

d) Откуда vend_no, vend_qty и shipping_method входят во вставку к PRODVENDOR? Это единственная очевидная ошибка компиляции, которая выскакивает.

e) Вы не указываете столбцы таблицы во вставках. Это приведет к ошибке компиляции, если у вас есть значения в неправильном порядке или отсутствуют, но вы не можете сказать, просто посмотрев код. (Вы не сказали, что это за ошибки «так может» после изменения @ WW, так что не знаете, относится ли это к делу). И если позже добавится еще один столбец, этот триггер станет недействительным, поэтому обычно рекомендуется явно перечислить столбцы.

Функционально вы, похоже, отправляете электронное письмо, в котором говорится, что весь заказ находится на обратном заказе, а не только этот продукт; и, кажется, нет никакой связи между текущим порядком и тем, что вы вводите в BACKORDER и PRODVENDOR.

2 голосов
/ 12 апреля 2011

Измените эту строку:

QOH = :old.QOH - :new.QTY

на

QOH := :old.QOH - :new.QTY

В PL / SQL := является оператором присваивания, поэтому используйте его при установке переменной PL / SQL.

Каким бы ни был источник ваших ошибок компиляции, отправка электронного письма из триггера кажется плохой идеей.

0 голосов
/ 12 апреля 2011

Вы уверены, что QOH - это поле в таблице ORDERLINE? Старый. и: НОВЫЙ. ключевые слова применимы только к таблице, на которой установлен триггер.

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