【问题标题】:Update Column in a table using triggers while inserting value in another table在另一个表中插入值时使用触发器更新表中的列
【发布时间】:2023-04-06 23:32:01
【问题描述】:

所以基本上我有这 3 个表及其列,

tbl_equipment ----> (equip_id,equip_price)

tbl_equiporder ----> (equip_id,proj_no,qty)

tbl_project -----> (proj_no,proj_balance)

tbl_equiporder 表中插入值时,我需要编写一个更新proj_balance 的触发器。

需要用到的公式是

balance = balance -(price*qty)

我需要从tbl_equiporder 获取数量值,同时为同一个提到的表编写插入语句,以便我可以使用它来更新tbl_project 中的余额

我编写了以下触发器来更新 proj_balance 在插入tbl_equiporder 表时

CREATE OR REPLACE TRIGGER trigger_equiporder
AFTER INSERT OR UPDATE OR DELETE ON tbl_equiporder FOR EACH ROW    
  DECLARE
    t_equipid NUMBER(4);
    t_price   NUMBER(4);
    t_qty     NUMBER(4);
    t_balance NUMBER(4);
  BEGIN

    SELECT equip_id, equip_price INTO t_equipid, t_price
      FROM tbl_equipment@fit5043a
     WHERE equip_id = :new.equip_id;

    SELECT equip_qty INTO t_qty
      FROM tbl_equiporder
     WHERE equip_id = :new.equip_id;

    SELECT proj_balance INTO t_balance
      FROM tbl_project
     WHERE proj_no = :new.proj_no;

    t_balance := t_balance - (t_price * t_qty);

    UPDATE tbl_project
       SET proj_balance = t_balance
     WHERE proj_no = :new.proj_no;

  END;

当我写插入语句时

INSERT INTO tbl_equiporder VALUES (1, 101, 1);

它抛出了以下错误

Error starting at line 1 in command:
INSERT INTO tbl_equiporder VALUES (1,101,'11-sep-13',1000,1)
Error report:
SQL Error: ORA-04091: table S24585181.TBL_EQUIPORDER is mutating, trigger/function may not see it
ORA-06512: at "S24585181.TRIGGER_EQUIPORDER", line 9
ORA-04088: error during execution of trigger 'S24585181.TRIGGER_EQUIPORDER'
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it"
*Cause:    A trigger (or a user defined plsql function that is referenced in
           this statement) attempted to look at (or modify) a table that was
           in the middle of being modified by the statement which fired it.
*Action:   Rewrite the trigger (or function) so it does not read that table.

【问题讨论】:

    标签: sql oracle plsql triggers


    【解决方案1】:

    您是否阅读过有关此错误的信息?您无法从您在触发器中更改的表中进行选择。

    删除 SELECT 并只使用已经可用的值。

    create or replace trigger trigger_equiporder 
     after insert or update or delete on tbl_equiporder
     for each row  
    
    declare
       t_price number(4);
       t_qty number(4);
       t_balance number(4);
    begin
    
       select equip_price into t_price 
         from tbl_equipment@fit5043a 
        where equip_id = :new.equip_id;
    
       select proj_balance into t_balance 
         from tbl_project 
        where proj_no = :new.proj_no;
    
        t_balance := t_balance -(t_price * :new.equip_qty);
    
       update tbl_project 
          set proj_balance = t_balance 
        where proj_no = :new.proj_no;
    
    end;
    

    我会对所有这些都非常谨慎;您似乎在触发器中执行跨数据库 SELECT,这将大大减慢它的速度。似乎值得查看您的数据模型,看看它是否可以改进;即使它像在本地拥有tbl_equipment 的物化视图一样简单。

    您还通过数据库链接选择了不必要的数据,不要。我已经删除了它

    【讨论】:

    • 嗨,Ben,我尝试运行上述查询。而且我仍然遇到同样的错误。我应该摆脱选择吗?如果没有选择,我将如何获得我应该比较的值?
    • 你不能得到完全相同的错误@Advait...你能复制并粘贴 exact 错误吗?
    • 嗨 Ben,我收到以下错误错误从第 1 行开始在命令中:INSERT INTO tbl_equiporder VALUES (1,101,'11-sep-13',1000,1) 错误报告:SQL 错误: ORA-04091:表 S24585181.TBL_EQUIPORDER 正在变异,触发器/函数可能看不到它 ORA-06512:在“S24585181.TRIGGER_EQUIPMENT”,第 10 行 ORA-04088:执行触发器“S24585181.TRIGGER_EQUIPMENT”04091.00000 - 时出错表 %s.%s 正在变异,触发器/函数可能看不到它”
    • *原因:触发器(或此语句中引用的用户定义的 plsql 函数)试图查看(或修改)正在被触发的语句修改的表它。 *操作:重写触发器(或函数),使其不读取该表。
    • 在这种情况下,您没有使用我更改的触发器,因为它不是从TBL_EQUIPORDER 读取的;你可以看到。
    猜你喜欢
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多