2011-04-12 119 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

相关问题