Oracle

我不知道如何修復 ORA-04091 突變觸發錯誤

  • April 24, 2019

我正在學習 Oracle SQL,但是在處理觸發器時我發現了一個錯誤,這會阻止我更新該表中的值。

錯誤是:

錯誤 ORA-04091:表 USUARIO.LINEAS 正在變異,觸發器/函式可能看不到它 ORA-06512:在“USUARIO.TRG_ACTUALIZARPEDIDO”,第 5 行 ORA-04088:執行觸發器“USUARIO.TRG_ACTUALIZARPEDIDO”時出錯

我已經了解它,但無法找到解決方案或自己理解問題所在。

CREATE OR REPLACE TRIGGER trg_actualizarpedido
AFTER INSERT OR UPDATE OR DELETE ON LINEAS
FOR EACH ROW

DECLARE
   sumaImporteLineas NUMBER := 0;

BEGIN
   SELECT SUM(IMPORTE) INTO sumaImporteLineas FROM LINEAS WHERE NUMPEDIDO = :NEW.NUMPEDIDO;
   UPDATE PEDIDOS ped SET ped.TOTAL = sumaImporteLineas WHERE ped.NUM = :NEW.NUMPEDIDO;
END;

謝謝!

ORA-04091

這是甲骨文的說法:

你真的不想那樣做。

這是我的解決方法的簡短列表。

選項1

使用VIEW.

這是首選方法。

選項 2

使用Materialized View.

是的,您可以在送出時快速刷新 SUM()。

選項 3

使用 TAPI(表 API)。(一Package)

所有的 DML 操作都必須經過這個Package;永遠不要反對實際的桌子。

選項 4

3-觸發解決方案。(這可能是一個複雜的觸發器。)

如果沒有適當的鎖定,您可能會“失去更新”。

即使有適當的鎖定,也可能發生死鎖。

在對錶的更改做出反應的觸發器中,您不能查詢表本身。但你不需要。

看起來好像您正試圖根據 IMPORTE 值的更改來保持執行總計。為此,您不需要一個而是三個觸發器:

/* Insert - Add New value */ 
CREATE OR REPLACE TRIGGER trg_actualizarpedido1
AFTER INSERT ON LINEAS
FOR EACH ROW
BEGIN
   UPDATE PEDIDOS 
   SET TOTAL = TOTAL + :NEW.IMPORTE 
   WHERE NUMPEDIDO = :NEW.NUMPEDIDO ; 
END;

/* Update - Subtract the Old value, Add New value */ 
CREATE OR REPLACE TRIGGER trg_actualizarpedido2
AFTER UPDATE ON LINEAS
FOR EACH ROW
BEGIN
   UPDATE PEDIDOS 
   SET TOTAL = TOTAL - :OLD.IMPORTE + :NEW.IMPORTE 
   WHERE NUMPEDIDO = :NEW.NUMPEDIDO ; 
END;

/* Delete - Subtract the Old value */ 
CREATE OR REPLACE TRIGGER trg_actualizarpedido3
AFTER DELETE ON LINEAS
FOR EACH ROW
BEGIN
   UPDATE PEDIDOS 
   SET TOTAL = TOTAL - :OLD.IMPORTE 
   WHERE NUMPEDIDO = :OLD.NUMPEDIDO ; 
END;

引用自:https://dba.stackexchange.com/questions/235499