【问题标题】:Get ID of updated entry on Update trigger - mutating table error在更新触发器上获取更新条目的 ID - 变异表错误
【发布时间】:2012-12-18 00:46:19
【问题描述】:

我正在尝试创建更新触发器,但我一直遇到“变异表”错误。主要思想是一个带有用户评分的买卖数据库。 基本上我想,每次更新 PRODUTOS 表上的评级时,重新计算卖家的评级。 我正在尝试以下触发器(及其版本),但它无处可寻..

CREATE OR REPLACE TRIGGER actualiza_rating_vend
AFTER UPDATE OF RATING_VENDEDOR
ON PRODUTOS
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
    CURSOR prod IS
        SELECT ID_USER,RATING_VENDEDOR, ID_COMPRADOR, RATING_COMPRADOR
        FROM   PRODUTOS
        WHERE  PRODUTOS.ID_USER = :NEW.ID_USER
        OR     PRODUTOS.ID_COMPRADOR = :NEW.ID_USER;
     contador NUMBER;
     soma     NUMBER;
     res      NUMBER;
     linha    prod%ROWTYPE;
     username  varchar2(255);
     BEGIN
     res := 0;
     contador := 0;
     fetch prod into linha;  
     username := :NEW.ID_USER;
         while prod%found loop
          if(linha.ID_user = username)
          then
            soma := soma + linha.RATING_VENDEDOR;
          else
            soma := soma + linha.RATING_COMPRADOR;
          end if;
          contador := contador + 1;       
          fetch prod into linha;
        end loop;
    close prod;
         res := soma / contador;
         update USERS set USERS.RATING = res where USERS.ID_USER = username;
  end;

谁能给我一个提示,我怎样才能只选择 ID_USER 值等于更新条目的 ID_USER 的条目?.. 提前致谢!

【问题讨论】:

  • 您在问题文本中谈到了DEALS 表。但是您的触发器没有引用该表。我假设触发器是正确的,并且问题的文本是错误的,但如果你能澄清这一点会很有帮助。
  • 另外,RATING_VENDEDOR 表上的UPDATE 是否来自PRODUTOSUSERS 上的另一个触发器(或从另一个触发器调用的代码)?
  • @JustinCave 抱歉,我写了 Deals 是因为 'produtos' 是一个葡萄牙语单词,它可能很奇怪(但我把它弄得更糟了,哈哈)我已经编辑了正确的表名。不,RATING_VENDEDOR 上的更新不是来自另一个触发器,它是直接的 sql 更新命令..再次,抱歉
  • 如果UPDATE 不是来自另一个触发器(或由另一个触发器调用的东西),我很难看到这将如何引发变异表异常,因为它没有尝试查询定义触发器的表。 UPDATE 正在从另一个触发器发出(直接或间接),或者没有从该触发器引发变异表异常。
  • 你真的想从触发器重新计算它吗?动态计算它的视图(或物化视图)是否适用于此?我想可能取决于更新和查询频率。

标签: oracle plsql mutating-table


【解决方案1】:

如果USERS表格中的评分是最新的,您只需添加最新更改的评分:

CREATE OR REPLACE TRIGGER actualiza_rating_vend
  AFTER UPDATE ON produtos FOR EACH ROW
BEGIN
   UPDATE users 
      SET user_rating = user_rating + :new.rating_vendedor - :old.rating_vendedor
    WHERE id_user = :new.id_user;

   UPDATE users 
      SET user_rating = user_rating + :new.rating_comprador - :old.rating_comprador
   WHERE id_user = :new.id_comprador;

END actualiza_rating_vend;

/

【讨论】:

  • 这样我只更新了 PRODUTOS 上的 rating_vendor 的值,而不是 USERS 表上的值。也许我没有正确解释自己:每个用户都有一个评分值,它来自平均值他出售的物品的评分。因此,当他获得新评级时,我必须重新计算平均“全球”评级..
  • 我不会重新计算每次更新的平均值,而是利用平均值 = 总和 / 计数。上面的触发器总结了评分,你只需要添加一个计数列,你就有了平均值,无需重新计算。
猜你喜欢
  • 1970-01-01
  • 2015-06-17
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
相关资源
最近更新 更多