我的PLSQL触发器未遍历表

时间:2019-04-30 16:16:33

标签: sql oracle plsql oracle-apex

我有一个小组项目,我们正在使用PLSQL制作购物车应用程序。我们正在创建触发器,以取消购物车并将所有商品退还库存。现在,如果您将多个商品添加到购物车中,则在触发器运行时,它只会添加一种产品(不是全部)的库存,因此出于某种原因,触发器不会循环通过。我们的项目明天到期,所以请帮忙!

create or replace TRIGGER Cancel
Before delete on sc_cart
For each row

DECLARE
ws_prod_id number(3,0);
ws_item_quantity_in_cart number(7,0);

BEGIN

/*product and quantity in cart*/
select max(item_product_id), max(item_quantity_in_cart) into ws_prod_id, ws_item_quantity_in_cart
from sc_items
where item_cart_id = :old.cart_id;

update sc_product set prod_quan_avail = prod_quan_avail + ws_item_quantity_in_cart where ws_prod_id = prod_id;
update sc_product set prod_quan_sold = prod_quan_sold - ws_item_quantity_in_cart where ws_prod_id = prod_id;

delete from sc_items
where :old.cart_id = item_cart_id;

END;

我们需要代码来遍历表格的每一行,并将购物车中的每件物品退还给库存。

2 个答案:

答案 0 :(得分:2)

我敦促您不要将所有这些代码都放入触发器中,而应创建如下的cancel_order过程:

CREATE OR REPLACE PROCEDURE cancel_card (cart_id_in IN INTEGER)
IS
   ws_prod_id                 NUMBER (3, 0);
   ws_item_quantity_in_cart   NUMBER (7, 0);
BEGIN
   /*product and quantity in cart*/
   SELECT MAX (item_product_id), MAX (item_quantity_in_cart)
     INTO ws_prod_id, ws_item_quantity_in_cart
     FROM sc_items i
    WHERE i.item_cart_id = cancel_card.cart_id_in;

   UPDATE sc_product p
      SET prod_quan_avail = prod_quan_avail + ws_item_quantity_in_cart,
          prod_quan_sold = prod_quan_sold - ws_item_quantity_in_cart
    WHERE p.prod_id = cancel_card.ws_prod_id;

   DELETE FROM sc_items o
         WHERE i.cart_id = cancel_card.cart_id_in;

   DELETE FROM sc_cart c
         WHERE c.cart_id = cancel_card.cart_id_in;
END;

然后根据需要调用此过程,而不是从触发器内部调用。

您应避免在触发器内使用SQL语句。副作用和突变表错误的可能性太大。

答案 1 :(得分:2)

执行此操作时:

   SELECT MAX (item_product_id), MAX (item_quantity_in_cart)
     INTO ws_prod_id, ws_item_quantity_in_cart
     FROM sc_items i
    WHERE i.item_cart_id = cancel_card.cart_id_in;

您只是选择一种(1)产品=> max(item_product_id)

所以,那是唯一更新的产品,而且更糟的是,最终它将通过另一个产品的max(qty)进行更新...

您需要一个光标查看购物车产品,并针对每种产品进行必要的更新。

触发器不是好事,但作为基本规则,我完全同意史蒂文·费尔斯坦的观点,应避免使用它们。但是有时候你做不到。

也许更好的设计可能是混合设计: -构建基于购物车ID清除购物车的存储过程 -从触发器(如果确实需要)或从外部(购物车管理过程)调用该过程作为更好的选择。