此处不允许列

发布于 2024-10-31 20:08:10 字数 1260 浏览 0 评论 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。如果没有,请向客户发送电子邮件,更新延期交货表,然后应从供应商处订购产品。

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
--------------------------------------------------------------------------------

Product table (P_no, QOH, etc)

Orderline table (OL_no, QTY, etc)

Backorder table (B_no, B_QTY, etc)

Vendor table (V_no, etc)

I need to make sure that when a customer buys a product, there is enough QOH in product table, if there is, QOH in Product should be decreased (updated). If not, send email to customer, update the backorder table and the product should be ordered from the vendor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

会发光的星星闪亮亮i 2024-11-07 20:08:10

将此行更改为:

QOH = :old.QOH - :new.QTY

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

PL/SQL 中 := 是赋值运算符,因此在设置 PL/SQL 变量时使用它。

无论编译错误的来源是什么,从触发器发送电子邮件似乎都是一个坏主意。

Change this line:

QOH = :old.QOH - :new.QTY

to

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

In PL/SQL := is the assignment operator, so use it when you are setting a PL/SQL variable.

Whatever the source of your compile errors, sending an email from a trigger seems like a bad idea.

喜你已久 2024-11-07 20:08:10

首先,考虑将插入放入过程而不是触发器中。 (也许还有一个更有用的名字)。如果其他表稍后获得自己的触发器,则从此处插入或更新其他表可能会变得混乱,并且很难跟踪何时何地发生了什么。

其次,这看起来不能很好地处理并发插入 - 同一产品的两个新 ORDERLINE 插入同时会尝试更新产品 QOH,结果可能是意外或不需要的结果 - 例如,QOH 可能会变为负数。您还可能会向供应商收到多个订单;每个请求缺货产品的订单行都将向供应商发出新订单,即使每个订单行数量为 1 并且您一次向供应商订购 100 个订单也是如此。

第三,各种代码错误;我将从几个更明显的开始:

a) 您使用 WHERE :old.product_no = :new.product_no 从 PRODUCTORDERLINE 中进行选择。我不确定 :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_methodPRODVENDOR 的插入中来自哪里?这是跳出的唯一明显的编译错误。

e) 您没有在插入中指定表列。如果您的值顺序错误或有任何缺失,这将导致编译错误,但仅通过查看代码无法判断。 (您还没有说 @WW 更改后的“so may”错误是什么,所以不知道这是否相关)。如果稍后添加另一列,则此触发器将变得无效,因此通常最好显式列出这些列。

从功能上讲,您似乎正在发送一封电子邮件,说明整个订单都处于延期交货状态,而不仅仅是该产品;并且当前订单与您在 BACKORDERPRODVENDOR 中输入的内容之间似乎没有任何链接。

Firstly, consider putting the insert into a procedure instead of a trigger. (And a more helpful name, maybe). Inserting to or updating other tables from here could get messy if they get their own triggers later, and it's hard to keep track of what's going on where and when.

Secondly, this looks like it won't handle concurrent inserts very well - two new ORDERLINE inserts for the same product at the same time will try to update the product QOH with probably unexpected, or undesirable, results - QOH can go negative, for example. You're also potentially going to get multiple orders to the vendor; every order line that requests an out-of-stock product is going to make a new order to the vendor, even if each order line quantity is 1 and you order 100 at a time from the vendor.

Thirdly, various code errors; I'll start with a couple of more obvious ones:

a) You're selecting from PRODUCT and ORDERLINE with WHERE :old.product_no = :new.product_no. I'm not sure :OLD is even set in a before-insert trigger, but if it is it will be the same as :NEW or null, so you're possibly going to get ORA-02112 or ORA-01403 errors as it'll find all rows, or maybe none.

b) Your select from ORDERLINE will return no rows on the first order line and multiple rows from the third onwards anyway, so again you'll get ORA-01403 and ORA-02112 errors. But it's pointless as you're just selecting the value you're querying on. You can just use the :NEW value in the email call.

c) Your update of PRODUCT has no WHERE clause, so all QOH values will be updated.

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) Where are vend_no, vend_qty and shipping_method coming from in the insert to PRODVENDOR? This is the only obvious compilation error that jumps out.

e) You aren't specifying the table columns in the inserts. This will cause a compilation error if you have the values in the wrong order, or any missing, but you can't tell just by looking at the code. (You haven't said what the 'so may' errors are after @WW's change, so don't know if this is relevant). And if another column is added later, this trigger will become invalid, so it's generally a good idea to list the columns explicitly.

Functionally you seem to be sending an email saying the whole order is on back-order, rather than just this product; and there don't seem to be any links between the current order and what you're putting in to BACKORDER and PRODVENDOR.

陌伤浅笑 2024-11-07 20:08:10

您确定 QOH 是 ORDERLINE 表中的字段吗? :旧。和:新的。关键字仅适用于安装了触发器的表。

Are you sure that QOH is a field in the ORDERLINE table? The :OLD. and :NEW. keywords are applicable only to the table on which the trigger is installed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文