创建触发器后,我收到警告:
由于编译错误而创建的触发器
我该怎么办?
SQL> create trigger customer_trig
2 BEFORE INSERT OR UPDATE OR DELETE ON customer1
3 FOR EACH ROW
4 BEGIN
5 set customer1.t_cost=customer1.pprice*customer1.tq
6 END;
7 /
Warning: Trigger created with compilation errors.
SQL> desc customer1;
Name Null? Type
----------------------------------------- -------- ----------------------------
CID VARCHAR2(10)
NAME VARCHAR2(20)
PNAME VARCHAR2(15)
PPRICE NUMBER(5)
TQ NUMBER(5)
T_COST NUMBER(7)
SQL> insert into customer1 values('ssr345','vikram','book',30,12,0);
insert into customer1 values('ssr345','vikram','book',30,12,0)
*
ERROR at line 1:
ORA-04098: trigger 'RAYUDU.CUSTOMER_TRIG' is invalid and failed re-validation
您没有正确使用触发器。您必须使用:NEW
来引用新值,并且此处不需要ON DELETE
事件。
我认为您需要以下内容:
CREATE TRIGGER CUSTOMER_TRIG BEFORE
INSERT OR UPDATE
--OR DELETE
ON CUSTOMER1
FOR EACH ROW
BEGIN
:NEW.T_COST := :NEW.PPRICE * :NEW.TQ;
END;
/
正如@jarlh询问的,Oracle确实具有计算列。在Oracle中,这是一个虚拟专栏。并且是这里最好的解决方案。将列T_COST重新定义为虚拟列。如果您的表已经存在,则:
alter table customer1 drop column t_cost;
alter table customer1 add ( t_cost number(7) generated always as (pprice * tq ) virtual);
注:以上内容不需要“始终生成”而不是“虚拟”短语,但是确实提高了可读性(至少是IMO);