Oracle触发器在插入或更新另一个表时更新该表
我有两个表(主明细表)用于记录订单,我需要创建一个触发器,该触发器允许我使用“小计”字段中的小计和更新主表中的“总计”字段(与外键“ID\u ORDEN”相关的明细表),但我得到了一个错误的触发器 表:Oracle触发器在插入或更新另一个表时更新该表,oracle,triggers,Oracle,Triggers,我有两个表(主明细表)用于记录订单,我需要创建一个触发器,该触发器允许我使用“小计”字段中的小计和更新主表中的“总计”字段(与外键“ID\u ORDEN”相关的明细表),但我得到了一个错误的触发器 表: CREATE TABLE "ENCABEZADO_ORDEN" ("ID_ENCABEZADO" NUMBER(10,0), "NUMERO_ORDEN" NUMBER(10,0), "FECHA" DATE, "NOMBRE_CLIENTE" VARCH
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) 重命名表“ENCABEZADO_ORDEN”(即“ENCABEZADO_ORDEN_选项卡”)和2)禁用/删除“TOTAL_GENERAL”字段,然后3)创建原始名称为“ENCABEZADO_ORDEN”的视图,如下所示: 这将确保TOTAL_GENERAL始终正确(事实上,任何通过更新ENCABEZADO_ORDEN将其直接设置为其他值的操作都会立即导致语法错误)
如果性能是一个问题(即用户经常在ENCABEZADO\u ORDEN表中查询TOTAL\u GENERAL字段,查找DETALLE\u ORDEN中有大量详细记录的订单,导致Oracle重复获取和汇总大量小计)然后使用物化视图而不是基本视图。尝试通过谷歌搜索ORA-04091,了解变异表以及如何消除此错误。祝你一切顺利。
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'
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;