尝试在更新期间在触发器上读取 table,给出变异错误
Trying to read a table on Trigger during update, giving mutation error
在更新 table 之前,我必须插入另一个 table,但要完成此操作,我需要来自 table(和其他 table)的信息我正在更新,尝试在触发器中读取我的更新 table 时出错
ERROR at line 1:
ORA-04091: table BASEDATOS2.SOL_SOLICITUD_PREMIOS is mutating, trigger/function
may not see it
ORA-06512: at "BASEDATOS2.INS_AFTER_UPD_PRICES", line 10
ORA-04088: error during execution of trigger '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;
有人知道我怎样才能让它工作吗?
这里的问题是您的触发器是在 SOL_SOLICITUD_PREMIOS
上定义的,并且在触发器的主体中您正在从 SOL_SOLICITUD_PREMIOS 中选择数据。在 ROW 触发器中,您不允许读取、插入、更新或删除定义触发器的 table 中的其他行,因为它可能导致触发器循环,数据库在评估递归调用时卡住相同的触发器。但是,在这种情况下,不需要从 SOL_SOLICITUD_PREMIOS
读取数据,因为您已经在 :OLD
pseudo-row 中获得了所需的数据。如果我没看错,你可以按如下方式重写你的触发器,它应该能满足你的要求:
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;
祝你好运。
在更新 table 之前,我必须插入另一个 table,但要完成此操作,我需要来自 table(和其他 table)的信息我正在更新,尝试在触发器中读取我的更新 table 时出错
ERROR at line 1: ORA-04091: table BASEDATOS2.SOL_SOLICITUD_PREMIOS is mutating, trigger/function may not see it ORA-06512: at "BASEDATOS2.INS_AFTER_UPD_PRICES", line 10 ORA-04088: error during execution of trigger '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;
有人知道我怎样才能让它工作吗?
这里的问题是您的触发器是在 SOL_SOLICITUD_PREMIOS
上定义的,并且在触发器的主体中您正在从 SOL_SOLICITUD_PREMIOS 中选择数据。在 ROW 触发器中,您不允许读取、插入、更新或删除定义触发器的 table 中的其他行,因为它可能导致触发器循环,数据库在评估递归调用时卡住相同的触发器。但是,在这种情况下,不需要从 SOL_SOLICITUD_PREMIOS
读取数据,因为您已经在 :OLD
pseudo-row 中获得了所需的数据。如果我没看错,你可以按如下方式重写你的触发器,它应该能满足你的要求:
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;
祝你好运。