создать триггер в оракуле, который не позволит вставлять или обновлять с условием if - PullRequest
1 голос
/ 11 марта 2012

У меня есть две таблицы -

create table mobile
(
id int,
m_name  varchar(20),
purchase_date datetime
)


insert into mobile values('1','Samsung corby','12-JAN-12');
insert into mobile values('2','Nokia E5','15-MAR-12');
insert into mobile values('3','Sony Talk','10-FEB-12');



create table location
(
id int,
l_name varchar(20)
) 
insert into location values(1,'London');
insert into location values(2,'Washington');
insert into location values(3,'Mexico');

Я хочу создать триггер, который гарантирует, что sony talk mobile, которая находится в Мексике, не может быть приобретена в декабре. Это означает, что когда я пытаюсь вставить данныев мобильной таблице с идентификатором 3 и purchase_date как декабрь, триггер должен остановить его и дать соответствующее сообщение.

Мой код для этого -

create  or replace  trigger trg1
before insert or update
on mobile
for each row
declare
var1 number(4);  
begin
select id into var1 from location where l_name='Mexico';
    IF (:new.id = var1 and to_char(:new.purchase_date, 'MONTH') = 'DECEMBER') THEN 
        raise_application_error( -20001, 'THIS mobile CAN NOT BE PURCHASED NOW.');
    END IF; 
end; 

Триггер был создан, нокогда я пытаюсь вставить эти данные, используя этот код -

insert into mobile values('3','Sony Talk','10-JAN-11');

Триггер срабатывает, но выдает ошибку -

ORA-04098: trigger 'OPS$0924769.TRG1' is invalid and failed re-validation 

и мой код if также не работает должным образом--

    IF (:new.id = var1 and to_char(:new.purchase_date, 'MONTH') = 'DECEMBER') THEN 
        raise_application_error( -20001, 'THIS mobile CAN NOT BE PURCHASED NOW.');
    END IF; 

он не проверяет как id, так и дату покупки.Я дал buy_date как JAN, поэтому в этом случае триггер не должен срабатывать.Я в замешательстве.

1 Ответ

7 голосов
/ 11 марта 2012
  1. Ваш триггер был создан с ошибками компиляции. Если вы введете show errors после создания триггера, SQL * Plus отобразит вам синтаксические ошибки.
  2. В Oracle нет типа данных DATETIME. Тип данных столбца purchase_date в mobile должен быть DATE.
  3. Триггер, который вы разместили, компилируется и запускается в моей системе без ошибок, как только я исправляю ошибку при определении таблицы mobile
  4. Когда вы используете TO_CHAR с маской формата MONTH, результаты будут дополнены справа пробелами до длины самого длинного месяца (9 символов). Поскольку DECEMBER имеет всего 8 символов, ваше состояние никогда не будет оцениваться как TRUE. Вам нужно будет либо TRIM выводить, либо использовать маску формата fmMONTH, которая не заполняет вывод пробелами.

что-то вроде

create  or replace  trigger trg1
before insert or update
on mobile
for each row
declare
var1 number(4);  
begin
select id into var1 from location where l_name='Mexico';
    IF (:new.id = var1 and to_char(:new.purchase_date, 'fmMONTH') = 'DECEMBER') THEN 
        raise_application_error( -20001, 'THIS mobile CAN NOT BE PURCHASED NOW.');
    END IF; 
end; 

будет более вероятно, что вы ищете. Но это не объясняет, почему ваш триггер получает ошибки компиляции.

...