Oracle,ORA-04091 突变问题,更新 table 而不在触发器内触发触发器
Oracle, ORA-04091 mutation issues, updating a table without firing triggers within a trigger
我的问题是这样的:
我们公司正在销售带有数据输入的 BI 应用程序,它基本上 运行 对值发生变化的每一行进行更新。
- 我正在尝试为我们的用户构建一个功能来创建预算。
- 在我的 Table 中,我有 12 个帐户过帐字段(借方 - 贷方
那个月)和 12 个用于每个月的帐户余额。
- 我希望如果我的用户在过账上进行数据输入,那么几个月的余额
得到相应的更新,如果我的用户在
余额,过账相应调整
- 不能同时对过账和余额进行数据输入(2 个单独的
工作表)
我在 SQL 服务器中使用触发器检查过帐是否已更改,重新计算余额,反之亦然。
我尝试在 Oracle 中做同样的事情(我们必须同时支持两者,我不是 Oracle 专家)但我一直收到 Mutation 错误,我猜这是因为它卡在了一个循环中:
过帐 -> 更新余额 -> 更新过帐 -> 等
我环顾四周并尝试了不同的解决方案,例如在触发器内更新之前禁用触发器并在使用匿名事务后重新启用它,但更新无法解决。
我试图在触发器中添加一个更新为 1 的标志,并且仅当它的新值为 0 时才触发触发器(之后另一个触发器将其重置为 0)但它似乎并没有上班。
我尝试使用临时 table 来记录更改了哪些行以查看它是过帐更改还是余额更改,然后 运行 没有 FOR EACH ROW 的更新,但它仍然导致问题.
有人有什么想法吗?
代码是这样的:
CREATE OR REPLACE TRIGGER "QA_BUD_V8"."UPDATE_BUDGET_VALUES"
AFTER UPDATE OF
B_POSTING01,B_POSTING02,B_POSTING03,B_POSTING04,B_POSTING05,B_POSTING06,B_POSTING07,B_POSTING08,B_POSTING09,B_POSTING10,B_POSTING11,B_POSTING12
,B_OPENINGBALANCE
,B_ENDINGBALANCE01,B_ENDINGBALANCE02,B_ENDINGBALANCE03,B_ENDINGBALANCE04,B_ENDINGBALANCE05,B_ENDINGBALANCE06,B_ENDINGBALANCE07,B_ENDINGBALANCE08,B_ENDINGBALANCE09,B_ENDINGBALANCE10,B_ENDINGBALANCE11,B_ENDINGBALANCE12
ON "QA_BUD_V8".UDM_BUDGET_INWORK
FOR EACH ROW
BEGIN
IF (:OLD.B_OPENINGBALANCE <> :NEW.B_OPENINGBALANCE
OR :OLD.B_POSTING01 <> :NEW.B_POSTING01
OR :OLD.B_POSTING02 <> :NEW.B_POSTING02
OR :OLD.B_POSTING03 <> :NEW.B_POSTING03
OR :OLD.B_POSTING04 <> :NEW.B_POSTING04
OR :OLD.B_POSTING05 <> :NEW.B_POSTING05
OR :OLD.B_POSTING06 <> :NEW.B_POSTING06
OR :OLD.B_POSTING07 <> :NEW.B_POSTING07
OR :OLD.B_POSTING08 <> :NEW.B_POSTING08
OR :OLD.B_POSTING09 <> :NEW.B_POSTING09
OR :OLD.B_POSTING10 <> :NEW.B_POSTING10
OR :OLD.B_POSTING11 <> :NEW.B_POSTING11
OR :OLD.B_POSTING12 <> :NEW.B_POSTING12) THEN
[UPDATE Balances with Postings]
ELSIF (:OLD.B_ENDINGBALANCE01 <> :NEW.B_ENDINGBALANCE01
OR :OLD.B_ENDINGBALANCE02 <> :NEW.B_ENDINGBALANCE02
OR :OLD.B_ENDINGBALANCE03 <> :NEW.B_ENDINGBALANCE03
OR :OLD.B_ENDINGBALANCE04 <> :NEW.B_ENDINGBALANCE04
OR :OLD.B_ENDINGBALANCE05 <> :NEW.B_ENDINGBALANCE05
OR :OLD.B_ENDINGBALANCE06 <> :NEW.B_ENDINGBALANCE06
OR :OLD.B_ENDINGBALANCE07 <> :NEW.B_ENDINGBALANCE07
OR :OLD.B_ENDINGBALANCE08 <> :NEW.B_ENDINGBALANCE08
OR :OLD.B_ENDINGBALANCE09 <> :NEW.B_ENDINGBALANCE09
OR :OLD.B_ENDINGBALANCE10 <> :NEW.B_ENDINGBALANCE10
OR :OLD.B_ENDINGBALANCE11 <> :NEW.B_ENDINGBALANCE11
OR :OLD.B_ENDINGBALANCE12 <> :NEW.B_ENDINGBALANCE12) THEN
[UPDATE Postings with Balances]
END IF;
END;
触发器中是否有一种方法可以在不触发触发器的情况下进行更新或退出导致突变的循环?
不幸的是,我只能控制代码的某些 SQL 部分。我试图在应用程序中使用数据输入功能来进行预算,而不是在应用程序中明确地使用一个模块来进行预算,所以我能做的事情是有限的。
好的,看来你对我的评论有疑问,所以这里有一个代码示例,说明如何使用包变量来解决你的问题:
CREATE OR REPLACE PACKAGE pk_trigger_chk IS
suppress BOOLEAN := FALSE;
END pk_trigger_chk;
/
该包创建了您需要放入触发器定义中的变量。
CREATE OR REPLACE TRIGGER trg_1 AFTER UPDATE ON a FOR EACH ROW WHEN (new.val<>old.val)
BEGIN
IF NOT(pk_trigger_chk.suppress) THEN
pk_trigger_chk.suppress := TRUE;
UPDATE b
SET b.val = :new.val
WHERE b.id = :new.id;
pk_trigger_chk.suppress := FALSE;
END IF;
EXCEPTION WHEN OTHERS THEN
pk_trigger_chk.suppress := FALSE;
END trg_1;
/
这就是您更新触发器以使用包变量的方式。
这是一个正在运行的 DBFiddle。 DBFiddle 显示了使用包变量更新触发器之前和之后的情况。以及不使用它会出现的错误。 (LINK)
我找到了自己的答案。
最后还是太执着于AFTER UPDATE了。
我将其更改为 BEFORE UPDATE,做了一个 if 来检查是否是过帐或余额发生了变化,然后我在更新之前为另一组度量分配了一个新值,我的问题全部解决了......我浪费了 2 天在这个哈哈
如果有兴趣,这是代码
CREATE OR REPLACE TRIGGER "QA_BUD_V8"."UPDATE_BUDGET_VALUES"
BEFORE UPDATE ON "QA_BUD_V8".UDM_BUDGET_INWORK
FOR EACH ROW
DECLARE
v_CLOSE_TO_ACCOUNT varchar2(100);
BEGIN
SELECT count(CASE WHEN CLOSETOACCOUNT IS NOT NULL AND CLOSETOACCOUNT <> ' ' THEN 1 END) into v_CLOSE_TO_ACCOUNT FROM "QA_BUD_V8".UDM_ACCOUNTS WHERE COA = :OLD.COA AND ACCOUNTNUM = :OLD.ACCOUNTID;
IF (:OLD.B_OPENINGBALANCE <> :NEW.B_OPENINGBALANCE
OR :OLD.B_POSTING01 <> :NEW.B_POSTING01
OR :OLD.B_POSTING02 <> :NEW.B_POSTING02
OR :OLD.B_POSTING03 <> :NEW.B_POSTING03
OR :OLD.B_POSTING04 <> :NEW.B_POSTING04
OR :OLD.B_POSTING05 <> :NEW.B_POSTING05
OR :OLD.B_POSTING06 <> :NEW.B_POSTING06
OR :OLD.B_POSTING07 <> :NEW.B_POSTING07
OR :OLD.B_POSTING08 <> :NEW.B_POSTING08
OR :OLD.B_POSTING09 <> :NEW.B_POSTING09
OR :OLD.B_POSTING10 <> :NEW.B_POSTING10
OR :OLD.B_POSTING11 <> :NEW.B_POSTING11
OR :OLD.B_POSTING12 <> :NEW.B_POSTING12) THEN
:NEW.B_ENDINGBALANCE01 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01;
:NEW.B_ENDINGBALANCE02 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE03 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE04 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE05 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE06 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE07 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE08 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE09 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE10 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09 + :NEW.B_POSTING10
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN :NEW.B_ENDINGBALANCE09
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE11 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09 + :NEW.B_POSTING10 + :NEW.B_POSTING11
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 3 THEN :NEW.B_ENDINGBALANCE10
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN :NEW.B_ENDINGBALANCE09
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE12 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09 + :NEW.B_POSTING10 + :NEW.B_POSTING11 + :NEW.B_POSTING12
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 2 THEN :NEW.B_ENDINGBALANCE11
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 3 THEN :NEW.B_ENDINGBALANCE10
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN :NEW.B_ENDINGBALANCE09
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
ELSIF (:OLD.B_ENDINGBALANCE01 <> :NEW.B_ENDINGBALANCE01
OR :OLD.B_ENDINGBALANCE02 <> :NEW.B_ENDINGBALANCE02
OR :OLD.B_ENDINGBALANCE03 <> :NEW.B_ENDINGBALANCE03
OR :OLD.B_ENDINGBALANCE04 <> :NEW.B_ENDINGBALANCE04
OR :OLD.B_ENDINGBALANCE05 <> :NEW.B_ENDINGBALANCE05
OR :OLD.B_ENDINGBALANCE06 <> :NEW.B_ENDINGBALANCE06
OR :OLD.B_ENDINGBALANCE07 <> :NEW.B_ENDINGBALANCE07
OR :OLD.B_ENDINGBALANCE08 <> :NEW.B_ENDINGBALANCE08
OR :OLD.B_ENDINGBALANCE09 <> :NEW.B_ENDINGBALANCE09
OR :OLD.B_ENDINGBALANCE10 <> :NEW.B_ENDINGBALANCE10
OR :OLD.B_ENDINGBALANCE11 <> :NEW.B_ENDINGBALANCE11
OR :OLD.B_ENDINGBALANCE12 <> :NEW.B_ENDINGBALANCE12) THEN
:NEW.B_POSTING01 := :NEW.B_ENDINGBALANCE01 - :NEW.B_OPENINGBALANCE;
:NEW.B_POSTING02 := :NEW.B_ENDINGBALANCE02 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 12 THEN 0 ELSE :NEW.B_ENDINGBALANCE01 END;
:NEW.B_POSTING03 := :NEW.B_ENDINGBALANCE03 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 11 THEN 0 ELSE :NEW.B_ENDINGBALANCE02 END;
:NEW.B_POSTING04 := :NEW.B_ENDINGBALANCE04 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 10 THEN 0 ELSE :NEW.B_ENDINGBALANCE03 END;
:NEW.B_POSTING05 := :NEW.B_ENDINGBALANCE05 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN 0 ELSE :NEW.B_ENDINGBALANCE04 END;
:NEW.B_POSTING06 := :NEW.B_ENDINGBALANCE06 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN 0 ELSE :NEW.B_ENDINGBALANCE05 END;
:NEW.B_POSTING07 := :NEW.B_ENDINGBALANCE07 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN 0 ELSE :NEW.B_ENDINGBALANCE06 END;
:NEW.B_POSTING08 := :NEW.B_ENDINGBALANCE08 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN 0 ELSE :NEW.B_ENDINGBALANCE07 END;
:NEW.B_POSTING09 := :NEW.B_ENDINGBALANCE09 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN 0 ELSE :NEW.B_ENDINGBALANCE08 END;
:NEW.B_POSTING10 := :NEW.B_ENDINGBALANCE10 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN 0 ELSE :NEW.B_ENDINGBALANCE09 END;
:NEW.B_POSTING11 := :NEW.B_ENDINGBALANCE11 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 3 THEN 0 ELSE :NEW.B_ENDINGBALANCE10 END;
:NEW.B_POSTING12 := :NEW.B_ENDINGBALANCE12 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 2 THEN 0 ELSE :NEW.B_ENDINGBALANCE11 END;
END IF;
END;
我的问题是这样的:
我们公司正在销售带有数据输入的 BI 应用程序,它基本上 运行 对值发生变化的每一行进行更新。
- 我正在尝试为我们的用户构建一个功能来创建预算。
- 在我的 Table 中,我有 12 个帐户过帐字段(借方 - 贷方 那个月)和 12 个用于每个月的帐户余额。
- 我希望如果我的用户在过账上进行数据输入,那么几个月的余额 得到相应的更新,如果我的用户在 余额,过账相应调整
- 不能同时对过账和余额进行数据输入(2 个单独的 工作表)
我在 SQL 服务器中使用触发器检查过帐是否已更改,重新计算余额,反之亦然。
我尝试在 Oracle 中做同样的事情(我们必须同时支持两者,我不是 Oracle 专家)但我一直收到 Mutation 错误,我猜这是因为它卡在了一个循环中: 过帐 -> 更新余额 -> 更新过帐 -> 等
我环顾四周并尝试了不同的解决方案,例如在触发器内更新之前禁用触发器并在使用匿名事务后重新启用它,但更新无法解决。
我试图在触发器中添加一个更新为 1 的标志,并且仅当它的新值为 0 时才触发触发器(之后另一个触发器将其重置为 0)但它似乎并没有上班。
我尝试使用临时 table 来记录更改了哪些行以查看它是过帐更改还是余额更改,然后 运行 没有 FOR EACH ROW 的更新,但它仍然导致问题.
有人有什么想法吗? 代码是这样的:
CREATE OR REPLACE TRIGGER "QA_BUD_V8"."UPDATE_BUDGET_VALUES"
AFTER UPDATE OF
B_POSTING01,B_POSTING02,B_POSTING03,B_POSTING04,B_POSTING05,B_POSTING06,B_POSTING07,B_POSTING08,B_POSTING09,B_POSTING10,B_POSTING11,B_POSTING12
,B_OPENINGBALANCE
,B_ENDINGBALANCE01,B_ENDINGBALANCE02,B_ENDINGBALANCE03,B_ENDINGBALANCE04,B_ENDINGBALANCE05,B_ENDINGBALANCE06,B_ENDINGBALANCE07,B_ENDINGBALANCE08,B_ENDINGBALANCE09,B_ENDINGBALANCE10,B_ENDINGBALANCE11,B_ENDINGBALANCE12
ON "QA_BUD_V8".UDM_BUDGET_INWORK
FOR EACH ROW
BEGIN
IF (:OLD.B_OPENINGBALANCE <> :NEW.B_OPENINGBALANCE
OR :OLD.B_POSTING01 <> :NEW.B_POSTING01
OR :OLD.B_POSTING02 <> :NEW.B_POSTING02
OR :OLD.B_POSTING03 <> :NEW.B_POSTING03
OR :OLD.B_POSTING04 <> :NEW.B_POSTING04
OR :OLD.B_POSTING05 <> :NEW.B_POSTING05
OR :OLD.B_POSTING06 <> :NEW.B_POSTING06
OR :OLD.B_POSTING07 <> :NEW.B_POSTING07
OR :OLD.B_POSTING08 <> :NEW.B_POSTING08
OR :OLD.B_POSTING09 <> :NEW.B_POSTING09
OR :OLD.B_POSTING10 <> :NEW.B_POSTING10
OR :OLD.B_POSTING11 <> :NEW.B_POSTING11
OR :OLD.B_POSTING12 <> :NEW.B_POSTING12) THEN
[UPDATE Balances with Postings]
ELSIF (:OLD.B_ENDINGBALANCE01 <> :NEW.B_ENDINGBALANCE01
OR :OLD.B_ENDINGBALANCE02 <> :NEW.B_ENDINGBALANCE02
OR :OLD.B_ENDINGBALANCE03 <> :NEW.B_ENDINGBALANCE03
OR :OLD.B_ENDINGBALANCE04 <> :NEW.B_ENDINGBALANCE04
OR :OLD.B_ENDINGBALANCE05 <> :NEW.B_ENDINGBALANCE05
OR :OLD.B_ENDINGBALANCE06 <> :NEW.B_ENDINGBALANCE06
OR :OLD.B_ENDINGBALANCE07 <> :NEW.B_ENDINGBALANCE07
OR :OLD.B_ENDINGBALANCE08 <> :NEW.B_ENDINGBALANCE08
OR :OLD.B_ENDINGBALANCE09 <> :NEW.B_ENDINGBALANCE09
OR :OLD.B_ENDINGBALANCE10 <> :NEW.B_ENDINGBALANCE10
OR :OLD.B_ENDINGBALANCE11 <> :NEW.B_ENDINGBALANCE11
OR :OLD.B_ENDINGBALANCE12 <> :NEW.B_ENDINGBALANCE12) THEN
[UPDATE Postings with Balances]
END IF;
END;
触发器中是否有一种方法可以在不触发触发器的情况下进行更新或退出导致突变的循环? 不幸的是,我只能控制代码的某些 SQL 部分。我试图在应用程序中使用数据输入功能来进行预算,而不是在应用程序中明确地使用一个模块来进行预算,所以我能做的事情是有限的。
好的,看来你对我的评论有疑问,所以这里有一个代码示例,说明如何使用包变量来解决你的问题:
CREATE OR REPLACE PACKAGE pk_trigger_chk IS
suppress BOOLEAN := FALSE;
END pk_trigger_chk;
/
该包创建了您需要放入触发器定义中的变量。
CREATE OR REPLACE TRIGGER trg_1 AFTER UPDATE ON a FOR EACH ROW WHEN (new.val<>old.val)
BEGIN
IF NOT(pk_trigger_chk.suppress) THEN
pk_trigger_chk.suppress := TRUE;
UPDATE b
SET b.val = :new.val
WHERE b.id = :new.id;
pk_trigger_chk.suppress := FALSE;
END IF;
EXCEPTION WHEN OTHERS THEN
pk_trigger_chk.suppress := FALSE;
END trg_1;
/
这就是您更新触发器以使用包变量的方式。
这是一个正在运行的 DBFiddle。 DBFiddle 显示了使用包变量更新触发器之前和之后的情况。以及不使用它会出现的错误。 (LINK)
我找到了自己的答案。
最后还是太执着于AFTER UPDATE了。 我将其更改为 BEFORE UPDATE,做了一个 if 来检查是否是过帐或余额发生了变化,然后我在更新之前为另一组度量分配了一个新值,我的问题全部解决了......我浪费了 2 天在这个哈哈
如果有兴趣,这是代码
CREATE OR REPLACE TRIGGER "QA_BUD_V8"."UPDATE_BUDGET_VALUES"
BEFORE UPDATE ON "QA_BUD_V8".UDM_BUDGET_INWORK
FOR EACH ROW
DECLARE
v_CLOSE_TO_ACCOUNT varchar2(100);
BEGIN
SELECT count(CASE WHEN CLOSETOACCOUNT IS NOT NULL AND CLOSETOACCOUNT <> ' ' THEN 1 END) into v_CLOSE_TO_ACCOUNT FROM "QA_BUD_V8".UDM_ACCOUNTS WHERE COA = :OLD.COA AND ACCOUNTNUM = :OLD.ACCOUNTID;
IF (:OLD.B_OPENINGBALANCE <> :NEW.B_OPENINGBALANCE
OR :OLD.B_POSTING01 <> :NEW.B_POSTING01
OR :OLD.B_POSTING02 <> :NEW.B_POSTING02
OR :OLD.B_POSTING03 <> :NEW.B_POSTING03
OR :OLD.B_POSTING04 <> :NEW.B_POSTING04
OR :OLD.B_POSTING05 <> :NEW.B_POSTING05
OR :OLD.B_POSTING06 <> :NEW.B_POSTING06
OR :OLD.B_POSTING07 <> :NEW.B_POSTING07
OR :OLD.B_POSTING08 <> :NEW.B_POSTING08
OR :OLD.B_POSTING09 <> :NEW.B_POSTING09
OR :OLD.B_POSTING10 <> :NEW.B_POSTING10
OR :OLD.B_POSTING11 <> :NEW.B_POSTING11
OR :OLD.B_POSTING12 <> :NEW.B_POSTING12) THEN
:NEW.B_ENDINGBALANCE01 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01;
:NEW.B_ENDINGBALANCE02 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE03 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE04 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE05 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE06 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE07 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE08 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE09 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE10 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09 + :NEW.B_POSTING10
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN :NEW.B_ENDINGBALANCE09
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE11 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09 + :NEW.B_POSTING10 + :NEW.B_POSTING11
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 3 THEN :NEW.B_ENDINGBALANCE10
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN :NEW.B_ENDINGBALANCE09
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
:NEW.B_ENDINGBALANCE12 := :NEW.B_OPENINGBALANCE + :NEW.B_POSTING01 + :NEW.B_POSTING02 + :NEW.B_POSTING03+ :NEW.B_POSTING04 + :NEW.B_POSTING05 + :NEW.B_POSTING06 + :NEW.B_POSTING07 + :NEW.B_POSTING08 + :NEW.B_POSTING09 + :NEW.B_POSTING10 + :NEW.B_POSTING11 + :NEW.B_POSTING12
- CASE
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 2 THEN :NEW.B_ENDINGBALANCE11
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 3 THEN :NEW.B_ENDINGBALANCE10
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN :NEW.B_ENDINGBALANCE09
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN :NEW.B_ENDINGBALANCE08
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN :NEW.B_ENDINGBALANCE07
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN :NEW.B_ENDINGBALANCE06
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN :NEW.B_ENDINGBALANCE05
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN :NEW.B_ENDINGBALANCE04
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =10 THEN :NEW.B_ENDINGBALANCE03
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =11 THEN :NEW.B_ENDINGBALANCE02
WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD =12 THEN :NEW.B_ENDINGBALANCE01
ELSE 0
END;
ELSIF (:OLD.B_ENDINGBALANCE01 <> :NEW.B_ENDINGBALANCE01
OR :OLD.B_ENDINGBALANCE02 <> :NEW.B_ENDINGBALANCE02
OR :OLD.B_ENDINGBALANCE03 <> :NEW.B_ENDINGBALANCE03
OR :OLD.B_ENDINGBALANCE04 <> :NEW.B_ENDINGBALANCE04
OR :OLD.B_ENDINGBALANCE05 <> :NEW.B_ENDINGBALANCE05
OR :OLD.B_ENDINGBALANCE06 <> :NEW.B_ENDINGBALANCE06
OR :OLD.B_ENDINGBALANCE07 <> :NEW.B_ENDINGBALANCE07
OR :OLD.B_ENDINGBALANCE08 <> :NEW.B_ENDINGBALANCE08
OR :OLD.B_ENDINGBALANCE09 <> :NEW.B_ENDINGBALANCE09
OR :OLD.B_ENDINGBALANCE10 <> :NEW.B_ENDINGBALANCE10
OR :OLD.B_ENDINGBALANCE11 <> :NEW.B_ENDINGBALANCE11
OR :OLD.B_ENDINGBALANCE12 <> :NEW.B_ENDINGBALANCE12) THEN
:NEW.B_POSTING01 := :NEW.B_ENDINGBALANCE01 - :NEW.B_OPENINGBALANCE;
:NEW.B_POSTING02 := :NEW.B_ENDINGBALANCE02 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 12 THEN 0 ELSE :NEW.B_ENDINGBALANCE01 END;
:NEW.B_POSTING03 := :NEW.B_ENDINGBALANCE03 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 11 THEN 0 ELSE :NEW.B_ENDINGBALANCE02 END;
:NEW.B_POSTING04 := :NEW.B_ENDINGBALANCE04 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 10 THEN 0 ELSE :NEW.B_ENDINGBALANCE03 END;
:NEW.B_POSTING05 := :NEW.B_ENDINGBALANCE05 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 9 THEN 0 ELSE :NEW.B_ENDINGBALANCE04 END;
:NEW.B_POSTING06 := :NEW.B_ENDINGBALANCE06 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 8 THEN 0 ELSE :NEW.B_ENDINGBALANCE05 END;
:NEW.B_POSTING07 := :NEW.B_ENDINGBALANCE07 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 7 THEN 0 ELSE :NEW.B_ENDINGBALANCE06 END;
:NEW.B_POSTING08 := :NEW.B_ENDINGBALANCE08 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 6 THEN 0 ELSE :NEW.B_ENDINGBALANCE07 END;
:NEW.B_POSTING09 := :NEW.B_ENDINGBALANCE09 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 5 THEN 0 ELSE :NEW.B_ENDINGBALANCE08 END;
:NEW.B_POSTING10 := :NEW.B_ENDINGBALANCE10 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 4 THEN 0 ELSE :NEW.B_ENDINGBALANCE09 END;
:NEW.B_POSTING11 := :NEW.B_ENDINGBALANCE11 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 3 THEN 0 ELSE :NEW.B_ENDINGBALANCE10 END;
:NEW.B_POSTING12 := :NEW.B_ENDINGBALANCE12 - CASE WHEN v_CLOSE_TO_ACCOUNT <> 0 AND :NEW.START_PERIOD = 2 THEN 0 ELSE :NEW.B_ENDINGBALANCE11 END;
END IF;
END;