Попытка прочитать таблицу на Trigger во время обновления, выдавая ошибку мутации - PullRequest
1 голос
/ 26 мая 2019

Перед обновлением таблицы мне нужно вставить в другую таблицу, но для этого мне нужна информация из таблицы (и других таблиц), которую я обновляю, при попытке прочитать мою таблицу обновления в триггере выдает ошибку

ОШИБКА в строке 1: ORA-04091: таблица BASEDATOS2.SOL_SOLICITUD_PREMIOS мутирует, триггер / функция может не видеть этого ORA-06512: в "BASEDATOS2.INS_AFTER_UPD_PRICES", строка 10 ORA-04088: ошибка во время выполнения триггера 'BASEDATOS2.INS_AFTER_UPD_PRICES'

Вот мой триггер

    CREATE OR REPLACE TRIGGER INS_AFTER_UPD_PRICES BEFORE UPDATE OF CONCEDIDO ON SOL_SOLICITUD_PREMIOS 
FOR EACH ROW WHEN (new.CONCEDIDO = 'S')
DECLARE
    DESDE DATE;
    HASTA DATE;
    MONTO NUMBER;
    MAX_ID NUMBER;
    v_mov_premio NUMBER;
    CUENTA NUMBER;
BEGIN
    SELECT MAX(ID_MOVIMIENTO)+1 INTO MAX_ID FROM AHO_MOVIMIENTOS_CUENTA;
    SELECT SSP.FECHA_DESDE,SSP.FECHA_HASTA,SE.MONTO_COBERTURA INTO DESDE,HASTA,MONTO
    FROM SOL_SOLICITUD_PREMIOS SSP JOIN SOL_EVENTOS SE
    ON SE.COD_EVENTO = SSP.COD_EVENTO 
    WHERE SE.COD_EVENTO=:OLD.COD_EVENTO
    AND SSP.ID=:OLD.ID;

    select id_tipo into v_mov_premio
            from aho_tipo_movimiento
            where UPPER(nombre_tipo) like '%PAGO DE PREMIO/SUBSIDIO%';

    SELECT AM.ID_CUENTA INTO CUENTA 
    FROM AHO_MOVIMIENTOS_CUENTA AM
    JOIN AHO_TIPO_MOVIMIENTO ATM ON ATM.ID_TIPO=AM.ID_TIPO
    WHERE ATM.ID_TIPO='A' AND ROWNUM=1;

    INSERT INTO AHO_MOVIMIENTOS_CUENTA 
    VALUES(MAX_ID, SYSDATE, MONTO*(HASTA-DESDE),v_mov_premio,CUENTA );
END;

Кто-нибудь знает, как я могу заставить его работать?

1 Ответ

2 голосов
/ 26 мая 2019

Проблема здесь в том, что ваш триггер определен на SOL_SOLICITUD_PREMIOS, а в теле триггера ВЫ ВЫБИРАЕТЕ данные из SOL_SOLICITUD_PREMIOS. В триггерах ROW вам не разрешено читать, вставлять, обновлять или удалять другие строки в таблице, для которых определен триггер, поскольку это может вызвать цикл триггера, где база данных застревает, оценивая рекурсивные вызовы того же триггера. Однако в этом случае чтение данных из SOL_SOLICITUD_PREMIOS не требуется, поскольку у вас уже есть данные, которые вам нужны, в псевдоряде :OLD. Если я правильно читаю, вы можете переписать свой триггер следующим образом, и он должен сделать то, что вы ищете:

CREATE OR REPLACE TRIGGER INS_AFTER_UPD_PRICES
  BEFORE UPDATE OF CONCEDIDO ON SOL_SOLICITUD_PREMIOS 
  FOR EACH ROW
  WHEN (new.CONCEDIDO = 'S')
DECLARE
    MONTO         NUMBER;
    MAX_ID        NUMBER;
    v_mov_premio  NUMBER;
    CUENTA        NUMBER;
BEGIN
    SELECT MAX(ID_MOVIMIENTO)+1 INTO MAX_ID FROM AHO_MOVIMIENTOS_CUENTA;

    SELECT SE.MONTO_COBERTURA
      INTO MONTO
      FROM SOL_EVENTOS SE 
      WHERE SE.COD_EVENTO = :OLD.COD_EVENTO;

    select id_tipo
      into v_mov_premio
      from aho_tipo_movimiento
      where UPPER(nombre_tipo) like '%PAGO DE PREMIO/SUBSIDIO%';

    SELECT AM.ID_CUENTA
      INTO CUENTA 
      FROM AHO_MOVIMIENTOS_CUENTA AM
      JOIN AHO_TIPO_MOVIMIENTO ATM
        ON ATM.ID_TIPO = AM.ID_TIPO
      WHERE ATM.ID_TIPO = 'A' AND
            ROWNUM = 1;

    INSERT INTO AHO_MOVIMIENTOS_CUENTA 
    VALUES(MAX_ID,
           SYSDATE,
           MONTO * (:OLD.FECHA_HASTA - :OLD.FECHA_DESDE),
           v_mov_premio,
           CUENTA );
END INS_AFTER_UPD_PRICES;

Удачи.

...