ORA-54029: Virtual column cannot be updated in trigger body ORACLE 报错 故障修复 远程处理
文档解释
ORA-54029: Virtual column cannot be updated in trigger body
Cause: Attempted to change the value of virtual column in a trigger body”
Action: This is not valid, change the trigger definition.
左右
ORA-54029:虚拟列在触发器体内不能更新
错误说明:
ORA-54029是Oracle数据库的一种错误,当在触发器体里更新虚拟列时报出。内部细节显示该错误是由Oracle引擎本身传播的,说明尝试在触发器体里更新虚拟列是不被允许了。虚拟列是Oracle数据库12c中新出现的概念,是由表中已有数据派生出来的列。
常见案例
假设有一个表table1,其中有3列,分别为num1,num2,num3。要创建一个虚拟列sum,其值等于num1+num2+num3。在AS部分,我们会创建一个虚拟列:
sum number GENERATED ALWAYS AS (num1+num2+num3)
现在我们以此虚拟列sum为触发条件,创建一个触发器,该触发器将对表中sum值大于1000的行更新。如下创建触发器:
CREATE OR REPLACE TRIGGER table1_trig
BEFORE UPDATE OF sum ON table1
FOR EACH ROW
WHEN (NEW.sum > 1000)
BEGIN
UPDATE table1 SET sum = NEW.sum;
END;
执行该触发器时,将会报出ORA-54029错误,表明在触发器体内不能更新虚拟列。
解决方法:
1、从表中删除该虚拟列。可以使用alter table table1的形式,将该虚拟列从表中删除,对虚拟列的操作体现在“drop column”是alter table的形式,然后在触发器体里,只需要更新其它两列源数据即可,即保留虚拟列的触发器:
CREATE OR REPLACE TRIGGER table1_trig
BEFORE UPDATE OF num1, num2 ON table1
FOR EACH ROW
WHEN (NEW.num1+NEW.num2 > 1000)
BEGIN
UPDATE table1 SET num1 = NEW.num1, num2 = NEW.num2;
END;
2、在触发器体里不更新虚拟列sum,只保留虚拟列条件:
CREATE OR REPLACE TRIGGER table1_trig
BEFORE UPDATE OF num1, num2 ON table1
FOR EACH ROW
WHEN (NEW.num1+NEW.num2 > 1000)
BEGIN
— DO NOT UPDATE sum
END;