Oracle 如何解决突变触发器

Oracle 如何解决突变触发器,oracle,plsql,triggers,mutating-table,Oracle,Plsql,Triggers,Mutating Table,我是PL/SQL ORACLE方面的新手 我有个问题,要触发一个变异表 我想实现以下几点:通过插入订单,在ORDER\u ITEMS表上,订单金额(数量)保留在表INVENTORY(QUANTITY\u ON\u HAND)的库存中 该键为ORDER_ID,按顺序递增 THE TABLE INVENTORIES -PRODUCT_ID -WHAREHOUSE_ID -QUANTITY_ON_HAND 我已经执行了一些函数,用于获取产品ID和表ORDER\U ITEMS中插入的最后一条记录的订购

我是PL/SQL ORACLE方面的新手 我有个问题,要触发一个变异表

我想实现以下几点:通过插入订单,在ORDER\u ITEMS表上,订单金额(数量)保留在表INVENTORY(QUANTITY\u ON\u HAND)的库存中

该键为ORDER_ID,按顺序递增

THE TABLE INVENTORIES
-PRODUCT_ID
-WHAREHOUSE_ID
-QUANTITY_ON_HAND
我已经执行了一些函数,用于获取产品ID和表ORDER\U ITEMS中插入的最后一条记录的订购数量

CREATE OR REPLACE FUNCTION get_data__order_quantity
RETURN number IS
quantity_order number;
BEGIN
 select quantity into quantity_order from (select * from ORDER_ITEMS order by order_id desc) where rownum=1;
 RETURN quantity_order ;
END get_data__order_quantity;

CREATE OR REPLACE FUNCTION get_data_cod_prod
RETURN number IS
cod_producto number;
BEGIN
 select product_id into cod_producto from (select * from ORDER_ITEMS order by order_id desc) where rownum=1;
 RETURN cod_producto ;
END get_data_cod_prod;
我已执行此表单的触发器

create or replace trigger actualizar_stock
after insert  --AFTER INSERT
on ORDER_ITEMS  -- ON TABLE ORDER_ITEMS
for each row

declare
 ctn_ordenada int;  --STORE THE AMOUNT OF ORDERED PRODUCTS
 cod_produc int;    --STORE THE ID OF THE PRODUCT THAT HAS BEEN ORDERED
 id_wharehouse int; --STORE THE ID OF THE FIRST WAREHOUSE ENCOUNTERED WITH THE PRODUCT IN EXISTENCE
 stock_bodega int;  --STORE THE EXISTENCE OF PRODUCTS (STOCK) IN BODEGA

begin
  ctn_ordenada:=get_data__order_quantity; --THE AMOUNT ORDERED FROM THE FUNCTION IS ASSIGNED
  cod_produc :=get_data_cod_prod;         -- THE PRODUCT ID IS ASSIGNED FROM THE FUNCTION

  select quantity_on_hand into stock_bodega   from inventories where (quantity_on_hand > 0 and rownum=1 and product_id=cod_produc); -- SE ASIGNA EL STOCK
  select  wharehouse_id into  id_wharehouse  from inventories where (quantity_on_hand > 0 and rownum=1 and product_id=cod_produc);  -- THE ID OF THE WAREHOUSE IS ASSIGNED

 -- IF THE ESTOCK IS GREATER THAN 0
 if (stock_bodega >0) then
 begin
 --UPDATE (REST THE CURRENT VALUE WITH THE ORDERED AMOUNT)
 update inventories set quantity_on_hand=quantity_on_hand-ctn_ordenada where wharehouse_id=id_wharehouse;
 end;
 else
  begin
  -- DO NOT UPDATE
  dbms_output.put_line('Registration not updated');
  end;
  end if;
end;

-- END OF THE TRIGGER

请帮助

基本问题是从触发器调用的函数
get\u data\u order\u quantity
get\u data\u cod\u prod
访问定义触发器的表。这将导致变异表异常

当然,另一个问题是,你的函数很可能不会达到你的目的。您说“我已经执行了获取产品ID和表ORDER\u项中插入的最后一条记录的订购量的函数”,但您的选择标准是
…其中ROWNUM=1
。没有办法提前知道该记录是什么——在没有特定选择或排序标准的情况下,数据库可以自由地以它关心的任何顺序返回行。它可能返回您插入的最后一行,但也可能返回表中的任意随机行。基于ROWNUM=1,您根本无法知道将在表中插入最后一行

幸运的是,您不需要执行任何操作,因为您已经可以访问刚刚通过
:NEW
伪行插入的行。我建议将您的触发器改写为:

create or replace trigger actualizar_stock
  after insert on ORDER_ITEMS
  for each row
begin
  --UPDATE (REST THE CURRENT VALUE WITH THE ORDERED AMOUNT)

  update inventories
    set quantity_on_hand = quantity_on_hand - :NEW.QUANTITY
    where QUANTITY_ON_HAND > 0 AND
          product_id = :NEW.PRODUCT_ID;

  IF SQL%ROWCOUNT = 0 THEN
    -- No rows updated
    dbms_output.put_line('Registration not updated');
  end if;
end actualizar_stock;

祝你好运。

为什么要用大写字母?请不要在堆栈溢出中尖叫。非常感谢您的澄清,并感谢它提出的解决方案。祝福
create or replace trigger actualizar_stock
  after insert on ORDER_ITEMS
  for each row
begin
  --UPDATE (REST THE CURRENT VALUE WITH THE ORDERED AMOUNT)

  update inventories
    set quantity_on_hand = quantity_on_hand - :NEW.QUANTITY
    where QUANTITY_ON_HAND > 0 AND
          product_id = :NEW.PRODUCT_ID;

  IF SQL%ROWCOUNT = 0 THEN
    -- No rows updated
    dbms_output.put_line('Registration not updated');
  end if;
end actualizar_stock;