当另一个表插入或更新时,Oracle触发器更新一个表
问题描述:
我有两个表(主 - 细节)用于记录命令,我需要创建一个触发器,允许我更新在其中的“TOTAL_GENERAL”字段主表与“SUBTOTAL”字段中的小计总和与外键“ID_ORDEN”相关的详细表中,但我得到触发器错误。当另一个表插入或更新时,Oracle触发器更新一个表
表:
CREATE TABLE "ENCABEZADO_ORDEN"
("ID_ENCABEZADO" NUMBER(10,0),
"NUMERO_ORDEN" NUMBER(10,0),
"FECHA" DATE,
"NOMBRE_CLIENTE" VARCHAR2(50),
"DIRECCION" VARCHAR2(50),
"TOTAL_GENERAL" NUMBER(10,0),
"LUGAR_VENTA" VARCHAR2(50),
CONSTRAINT "ENCABEZADO_ORDEN_PK" PRIMARY KEY ("ID_ENCABEZADO")
USING INDEX ENABLE
)
CREATE TABLE "DETALLE_ORDEN"
("ID_DETALLE" NUMBER(10,0),
"PRODUCTO" VARCHAR2(50),
"PRECIO_UNITARIO" NUMBER(10,2),
"CANTIDAD" NUMBER(10,0),
"SUBTOTAL" NUMBER(10,2),
"ID_ENCABEZADO" NUMBER(10,0),
CONSTRAINT "DETALLE_ORDEN_PK" PRIMARY KEY ("ID_DETALLE")
USING INDEX ENABLE
)
/
ALTER TABLE "DETALLE_ORDEN" ADD CONSTRAINT "DETALLE_ORDEN_FK" FOREIGN KEY ("ID_ENCABEZADO")
REFERENCES "ENCABEZADO_ORDEN" ("ID_ENCABEZADO") ENABLE
/
触发:
create or replace TRIGGER "CALCULAR_TOTAL_GENERAL"
BEFORE INSERT OR UPDATE ON "DETALLE_ORDEN"
FOR EACH ROW
DECLARE
V_ID_ENCABEZADO NUMBER(10,0);
BEGIN
SELECT "ID_ENCABEZADO"
INTO V_ID_ENCABEZADO
FROM "ENCABEZADO_ORDEN"
WHERE "ID_ENCABEZADO" = :NEW."ID_ENCABEZADO";
UPDATE "ENCABEZADO_ORDEN"
SET "TOTAL_GENERAL" = (SELECT SUM("SUBTOTAL") FROM "DETALLE_ORDEN"
WHERE "ID_ENCABEZADO" = V_ID_ENCABEZADO)
WHERE "ID_ENCABEZADO" = V_ID_ENCABEZADO;
END;
这是错误消息我收到的时候我插入或更新表 “DETALLE_ORDEN”:
1 error has occurred
ORA-04091: table CARLOSM.DETALLE_ORDEN is mutating, trigger/function may not see it
ORA-06512: at "CARLOSM.CALCULAR_TOTAL_GENERAL", line 9
ORA-04088: error during execution of trigger 'CARLOSM.CALCULAR_TOTAL_GENERAL'
答
不要使用这种逻辑的触发器(就此而言,不要使用触发器;总会有更好的方法)。另外,请尽可能避免在基表中存储冗余信息。
远更好的设计,以最小的影响现有的代码是 1)重命名表“ENCABEZADO_ORDEN”(即“ENCABEZADO_ORDEN_TAB”)和2)禁止/降“TOTAL_GENERAL”字段,然后3)创建的图原来的名字“ENCABEZADO_ORDEN”为:
CREATE OR REPLACE VIEW ENCABEZADO_ORDEN AS
SELECT O.*, (SELECT SUM(D.SUBTOTAL) FROM DETALLE_ORDEN D
WHERE D.ID_ENCABEZADO = O.ID_ENCABEZADO) TOTAL_GENERAL
FROM ENCABEZADO_ORDEN_TAB O;
这将确保TOTAL_GENERAL总是正确的(其实,任何的努力,通过ENCABEZADO_ORDEN的更新直接将其设置为其他值会导致立即语法错误)。
如果性能是一个问题(即用户经常查询的ENCABEZADO_ORDEN表TOTAL_GENERAL领域具有大量的DETALLE_ORDEN详细记录单,引发甲骨文反复取小计&和众人),然后使用物化视图,而不是基本的视图。
尝试使用Google搜索ORA-04091并了解变异表以及如何摆脱此错误。祝一切顺利。 – Utsav