【问题标题】:Trigger after insert with nested if conditions pl sql插入后触发嵌套if条件pl sql
【发布时间】:2020-11-19 12:43:06
【问题描述】:

我想在“order_items”表中插入后创建一个触发器。触发器是通过插入到“order_items”表中的数量减去“inventories”表中该产品 id 的数量。如果减去数量后的结果为负数,则将“库存”的数量改回原来的数量,并删除“订单项”中的数据(插入失败)。如果product id在多个仓库,那么只减去warehouse_id最小的数量

Example #1: 
Product ID '101' is available in Warehouse ID '1','2','3' 
So choose the product id '101' in warehouse id '1' (smallest) 
Product ID '101' Quantity in Inventories = 10 
Product ID '101' Quantity Order_Items = 15 
So 10-15=-5 (negative) 
So... 
Product ID '101' Quantity in Inventories = 10 (back to old data) 
Delete '101' datas from Order_Items


Example #2: 
Product ID '102' Quantity in Inventories = 20 
Product ID '102' Quantity Order_Items = 8 
So 20-8=12 
So... 
Product ID '102' Quantity in Inventories = 12

到目前为止,这是我的代码,有什么想法吗?谢谢!

CREATE OR REPLACE TRIGGER update_qty
AFTER INSERT
ON order_items
FOR EACH ROW 
DECLARE
qty_diff number;
qty_in number;
total number;
BEGIN
    select quantity,count(product_id) into qty_in,total
    from inventories
    where product_id=:new.product_id;
    if(total>1) then
    select product_id from inventories where warehouse_id=(select min(warehouse_id) from inventories);
    else
    qty_diff:=qty_in-:new.quantity;
    if(qty_diff<0) then
    i.quantity:=:old.quantity;
    delete from order_items where product_id=:new.product_id;
    else
    update inventories
    set quantity=qty_diff;
    end if;
    end if;
END;
/
BEGIN
insert into order_items(order_id,item_id,product_id,quantity,unit_price) values(12345,12345,12345,100,200);
END;
/

【问题讨论】:

  • 您是否遇到错误?如果是这样,有什么错误?有什么不工作吗?如果是这样,具体是什么?您已经发布了一些代码,但不是可重现的示例——如果您发布了一些表定义、示例数据和预期结果,您将处于一个很好的位置(理想情况下,即使有指向 livesql、dbfiddle 等页面的链接)一切都设置好了)。
  • 在我的脑海中,最初的select 正在执行count,但缺少group_id。您的if( total &gt; 1) 中的下一个查询缺少into,并且正在查看具有最小warehouse_id 的仓库而不是具有最小warehouse_id 的具有产品的仓库。你不想delete from order_items,你想抛出一个异常。如果您要使用 update inventories,则需要包含 where 子句,以便更新单行。
  • 退后一步,你最好有一个存储过程来插入order_items并调整inventories中的quantity,而不是把一堆逻辑放在一个触发。

标签: sql oracle plsql


【解决方案1】:

最好在插入时应用此逻辑(使用 DB 中的过程或应用程序级逻辑)。但是,如果您是出于学习目的而这样做并且我正确地遵循了您,则可以在触发器中使用以下简单的更新。

CREATE OR REPLACE TRIGGER UPDATE_QTY AFTER
    INSERT ON ORDER_ITEMS
    FOR EACH ROW
BEGIN
    -- check and update the INVENTORIES table 
    -- lowest warehouse id with the product will be selected
    -- new quantity or more must be available in the INVENTORIES table 
    UPDATE INVENTORIES I
       SET
        QUANTITY = QUANTITY - :NEW.QUANTITY
     WHERE QUANTITY >= :NEW.QUANTITY
       AND PRODUCT_ID = :NEW.PRODUCT_ID
       AND NOT EXISTS (
        SELECT 1
          FROM INVENTORIES II
         WHERE II.PRODUCT_ID = :NEW.PRODUCT_ID
           AND II.WAREHOUSE_ID < I.WAREHOUSE_ID
    );

    -- if no record is selected means product is not available in any of the lowest warehouse 
    IF SQL%ROWCOUNT = 0 THEN
        RAISE_APPLICATION_ERROR(
            -20000,
            'product not available in inventory'
        );
    END IF;
END;
/

【讨论】:

    猜你喜欢
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多