Plsql PL/SQL触发器引发一个变异表错误

Plsql PL/SQL触发器引发一个变异表错误,plsql,triggers,Plsql,Triggers,我有一个触发器: create or replace TRIGGER TR14_2 BEFORE INSERT OR UPDATE OF CANTIDAD ON DISTRIBUCION FOR EACH ROW DECLARE total_cars NUMBER; total_cars_potential NUMBER; BEGIN SELECT sum(cantidad) into total_cars FROM DISTRIBUCION WHERE cifc

我有一个触发器:

create or replace TRIGGER TR14_2 
BEFORE INSERT OR UPDATE OF CANTIDAD ON DISTRIBUCION 
FOR EACH ROW
DECLARE
  total_cars NUMBER;
  total_cars_potential NUMBER;
BEGIN
  SELECT sum(cantidad) into total_cars
    FROM DISTRIBUCION
    WHERE cifc = :NEW.cifc;
  total_cars_potential := total_cars + :NEW.cantidad;

  IF INSERTING THEN
    IF(total_cars_potential > 40) THEN
      raise_application_error(-20005, 'Dealer [' || :NEW.cifc || '] already has 40 cars stocked');
    END IF;
  END IF;

  IF UPDATING THEN
    IF(total_cars_potential - :OLD.cantidad > 40) THEN
      raise_application_error(-20006, 'That update of CANTIDAD makes the dealer exceeds the limit of 40 cars stocked');
    END IF;
  END IF;
END;
它得到了一个变异表错误,我已经检查过这是因为代码块的更新,插入正常;但是为什么呢?我怎样才能修好它

我想澄清一下,每个经销商最多可以有40辆车。因此,如果我在distribution(“distribution”)中添加一行cantidad(“quantity”),这将使经销商超过其最大库存,我将抛出一个错误。 但是,如果我更新了数据库中已经储存的某一类型的汽车数量,并且超过40辆,我还希望抛出一个异常


问题是,我没有在更新块上看到mutatig table错误。

触发器无法更改它从中读取的表。这就是变异表错误问题

您可以在下面的链接中看到提供的解决方案


触发器无法更改已从中读取的表。这就是变异表错误问题

您可以在下面的链接中看到提供的解决方案


1st:您得到突变表综合征的原因是您正在从触发器中更新的表中读取数据(选择总车辆数)

第二:解决方案:我可能会创建两个触发器:一个用于收集包变量中更新的行的行触发器

CREATE OR REPLACE PACKAGE PCK_TR14_2 IS
  TYPE changed_row IS RECORD (
        cantidad                DISTRIBUCION.cantidad%TYPE,
  );
  TYPE changed_row_table IS TABLE OF changed_rows INDEX BY binary_integer;
  changed_rows changed_row_table;
  cnt_changed_rows   BINARY_INTEGER   DEFAULT   1;
END PCK_TR14_2;
/
for each row触发器看起来像这样(现在是after insert!)

然后在after语句触发器中实现您的逻辑:

CREATE OR REPLACE TRIGGER TR14_2_S
AFTER INSERT OR UPDATE OF CANTIDAD ON DISTRIBUCION 
BEGIN
  FOR i IN PCK_TR14_2.changed_rows.FIRST..PCK_TR14_2.changed_rows.LAST LOOP
    -- YOUR LOGIC HERE
    null;
  END LOOP;
END;
/

根据需要访问“virtuell”表中的候选对象(PCK_TR14_2.changed_rows(i).CANTIDAD)

1:您获得突变表综合征的原因是您从触发器中更新的表中读取(选择总cars)

第二:解决方案:我可能会创建两个触发器:一个用于收集包变量中更新的行的行触发器

CREATE OR REPLACE PACKAGE PCK_TR14_2 IS
  TYPE changed_row IS RECORD (
        cantidad                DISTRIBUCION.cantidad%TYPE,
  );
  TYPE changed_row_table IS TABLE OF changed_rows INDEX BY binary_integer;
  changed_rows changed_row_table;
  cnt_changed_rows   BINARY_INTEGER   DEFAULT   1;
END PCK_TR14_2;
/
for each row触发器看起来像这样(现在是after insert!)

然后在after语句触发器中实现您的逻辑:

CREATE OR REPLACE TRIGGER TR14_2_S
AFTER INSERT OR UPDATE OF CANTIDAD ON DISTRIBUCION 
BEGIN
  FOR i IN PCK_TR14_2.changed_rows.FIRST..PCK_TR14_2.changed_rows.LAST LOOP
    -- YOUR LOGIC HERE
    null;
  END LOOP;
END;
/

根据需要访问“virtuell”表中的候选人(PCK_TR14_2.changed_rows(i).CANTIDAD)

检查此项检查此项检查,但就我而言,我不会更改触发点所在表中的任何内容。我只是读取:OLD和:NEW的值并将它们分配给变量。但是,就我而言,我并没有改变表中触发点所在的任何内容。我只是读了:旧的和:新的值,并将它们分配给变量。谢谢,这对于我们在课堂上所做的有点复杂,但它似乎可以顺利进行,我会尝试一下,并在最近的某一天看到。谢谢!谢谢,这对我们在课堂上所做的事情来说有点复杂,但似乎一切都会好起来的,我会在这几天试试看,谢谢!