TRIGGER будет выполняться при обновлении свойства? - PullRequest
1 голос
/ 29 ноября 2011

У меня проблема с триггерами, и я не могу найти почему.

Это таблицы:

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))

Я пытаюсь написать триггер, который будет выполнен при обновлении PROPERTY, когда поле состояния будет изменено с «НОВОГО» на «УТВЕРЖДЕНО», затем обновить дату истечения с сегодняшней датой Sysdate + 90 days.

Я пытаюсь это, но это не работает:

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 с внешним ключом из таблицы свойств? Или это правильно, но я что-то упустил?

Ответы [ 2 ]

2 голосов
/ 29 ноября 2011

Вы не можете изменить значение в триггере AFTER. Вам нужно будет использовать BEFORE триггер.

Если вы используете Oracle 11.2, вы должны получить ошибку «ORA-04084: невозможно изменить новые значения для этого типа триггера», если вы попытаетесь определить триггер AFTER, который изменяет значение

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.
0 голосов
/ 29 ноября 2011

Вам нужно будет выбрать из таблицы типов услуг, чтобы увидеть фактическое описание услуг, чтобы вы могли сравнить описания до и после.

Также вам придется изменить это на до обновлениясрабатывает при изменении значений, которые будут вставлены.

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
...