我想创建一些东西来自动更新表中的数据,但是我不知道该怎么用。
我有nr1个表
create table NR1
(
id INTEGER not null,
price INTEGER,
price2 INTEGER,
start_date DATE,
end_date DATE,
duration NUMBER
)
并且我尝试创建触发器,该触发器将在插入或更新表end_date之后始终更新,所以我尝试了以下操作:
create or replace trigger update_nr1_date
after update or insert on nr1
for each row
when (new.id>0)
declare
begin
UPDATE nr1
set nr1.end_date =add_months(nr1.start_date, nr1.duration);
end;
但是它有突变问题,我对此有所了解,并且我理解了这一概念。我想要这样的触发器(不是sheduler,因为我想在插入或更新某些行后自动获取它)。在将数据插入表本身时是否可以补充丢失的列?
答案 0 :(得分:4)
您的触发器需要在更新之前 才能更改触发器再次触发的行中的值;并且它需要通过赋值语句来修改the current row's (new) pseudorecord-您不应在触发器内发布单独的更新语句。首先,它将级联,在您的示例中woudl尝试更新表中的每一行。但这也导致变异表错误-您正在尝试更新触发器所针对的表中的行。有一些变通办法实际上是有必要的,但不在这里,该更新不应该存在。
所以您会这样做:
create or replace trigger update_nr1_date
before update or insert on nr1
for each row
when (new.id>0)
begin
:new.end_date := add_months(:new.start_date, :new.duration);
end;
/
但是如果您的体重在11g或更高,则可以use a virtual column instead,完全不需要触发器:
create table NR1
(
id INTEGER not null,
price INTEGER,
price2 INTEGER,
start_date DATE,
end_date DATE generated always as (add_months(start_date, duration)) virtual,
duration NUMBER
)
然后,当您插入时,跳过语句中的该列:
insert into nr1 (id, price, price2, start_date, duration)
values (1, 2, 3, date '2018-06-01', 3);
1 row inserted.
select * from nr1 where id = 1;
ID PRICE PRICE2 START_DATE END_DATE DURATION
---------- ---------- ---------- ---------- ---------- ----------
1 2 3 2018-06-01 2018-09-01 3
结束日期总是反映其他两列的值。