我遇到触发器问题,但我找不到原因。
这些是表格:
create table Properties(
idProperties number(10) NOT NULL ,
Type varchar2(45) NOT NULL,
ConstructionDate date NOT NULL,
FloorLocation varchar(20),
Balkony varchar2(10),
Price number(10) NOT NULL,
DateOfInsert date NOT NULL,
DateOfExiration date NOT NULL,
Address_FK number(20),
PropertyType_FK number(20) NOT NULL,
Service_FK number(20),
Ownership_FK number(20),
PropertyService_FK number(20))
create table Services(
idServices number(10) NOT NULL,
servicetype varchar2(20))
我正在尝试在状态字段从“NEW”更改为“APROVED”时编写一个触发器,以便在更新PROPERTY时执行,然后使用今天的日期(Sysdate)+ 90天更新到期日期。
我正在尝试这个,但它不起作用:
CREATE OR REPLACE TRIGGER T22
AFTER UPDATE ON Properties
FOR EACH ROW
Begin
if :new.servicetype = 'APROVED' then
:new.Servicetype := SYSDATE + 90;
end if;
End;
我是否需要使用属性表中的外键调用servicetype
?或者这是对的,但我错过了什么?
答案 0 :(得分:2)
您无法更改AFTER
触发器中的值。您需要使用BEFORE
触发器。
如果您使用的是Oracle 11.2,如果您尝试定义更改值的AFTER
触发器,则应该出现“ORA-04084:无法更改此触发类型的新值”错误
SQL> create table t (
2 col1 number,
3 col2 date
4 );
Table created.
SQL> create trigger trg_t
2 after update on t
3 for each row
4 begin
5 :new.col2 := sysdate + 90;
6 end;
7 /
create trigger trg_t
*
ERROR at line 1:
ORA-04084: cannot change NEW values for this trigger type
另一方面,如果您将触发器创建为BEFORE UPDATE
触发器,则它应该可以正常工作
SQL> ed
Wrote file afiedt.buf
1 create or replace trigger trg_t
2 before update on t
3 for each row
4 begin
5 :new.col2 := sysdate + 90;
6* end;
SQL> /
Trigger created.
答案 1 :(得分:0)
您必须从服务类型表中进行选择才能看到实际的服务描述,以便您可以比较之前和之后的描述。
此外,在更改即将插入的值时,您必须将此更改为更新前的触发器。
SQL> select * from properties;
ID SERVICEID EXPIRATIO
---------- ---------- ---------
100 1 26-FEB-12
200 2 28-NOV-11
SQL> select * from services;
SERVICEID SERVICETYPE
---------- --------------------
1 APPROVED
2 NEW
触发器定义:
create or replace trigger trg1
before update on properties
for each row
declare
l_old_servicetype services.servicetype%type;
l_new_servicetype services.servicetype%type;
begin
dbms_output.put_line('changing from ');
select servicetype
into l_old_servicetype
from services
where ServiceId = :old.serviceId;
select servicetype
into l_new_servicetype
from services
where ServiceId = :new.serviceId;
dbms_output.put_line('old value : ' || l_old_servicetype );
dbms_output.put_line('nwe value : ' || l_new_servicetype );
if( l_old_servicetype = 'NEW' and l_new_servicetype='APPROVED') then
:new.expirationDate := SYSDATE + 90;
end if;
end;
/
测试:
SQL> select * from properties;
ID SERVICEID EXPIRATIO
---------- ---------- ---------
100 2 28-NOV-11
200 2 28-NOV-11
SQL> update properties set serviceId = 1 where id = 100;
changing from
old value : NEW
nwe value : APPROVED
1 row updated.
SQL> select * from properties;
ID SERVICEID EXPIRATIO
---------- ---------- ---------
100 1 26-FEB-12
200 2 28-NOV-11