2011-04-12 91 views
0
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應該減少(更新)。如果沒有,發送電子郵件給客戶,更新延期交貨表,產品應從供應商處訂購。

回答

2

改變這一行:

QOH = :old.QOH - :new.QTY 

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

在PL/SQL :=是賦值運算符,所以使用它,當你設置一個PL/SQL變量。

無論您的編譯錯誤的來源是什麼,從觸發器發送電子郵件似乎是一個壞主意。

+0

謝謝,我試着改變賦值運算符,但我仍然收到如此多的錯誤。 – indolent 2011-04-12 03:01:36

0

您確定QOH是ORDERLINE表中的一個字段嗎?老人。和:NEW。關鍵字僅適用於安裝觸發器的表。

2

首先,考慮將插入代入觸發器而不是觸發器。 (也許更有用的名字)。如果以後插入或更新其他表格可能會變得雜亂,如果他們稍後獲得自己的觸發器,並且很難跟蹤發生在何時何地的事情。其次,這看起來好像不能很好地處理併發插入 - 同一產品同時插入兩個新的ORDERLINE會嘗試更新產品QOH,可能帶來意想不到的結果或不良結果 - QOH可以去消極的,例如。您也有可能向供應商獲取多個訂單;即使每個訂單行數量爲1,並且您每次從供應商訂購100個訂單,每個請求缺貨產品的訂單行都會向供應商發出新訂單。

第三,各種代碼錯誤;我將從幾個更明顯的開始:

a)您正在從PRODUCTORDERLINE中選擇WHERE :old.product_no = :new.product_no。我不確定:OLD甚至在插入前觸發器中設置,但如果它是:NEW或null,那麼您可能會得到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_novend_qtyshipping_method從插入來PRODVENDOR?這是跳出的唯一明顯的編譯錯誤。

e)您沒有在插入中指定表格列。這會導致編譯錯誤,如果你有錯誤的順序或缺少的值,但你不能通過查看代碼來判斷。 (你沒有說過@WW改變後的'可能'錯誤是什麼,所以不知道這是否相關)。如果稍後添加另一列,則此觸發器將變爲無效,因此通常明確列出列是一個好主意。

從功能上看,您似乎在發送一封電子郵件,說整個訂單都是在後面的訂單上,而不僅僅是這個產品。並且目前的訂單與您要投入BACKORDERPRODVENDOR之間似乎沒有任何關聯。

+0

這可能比預期的要嚴厲得多。也許我心情比今天早上意識到的還要糟糕...... – 2011-04-12 22:05:12

相關問題