在oracle中创建一个触发器,它不允许使用if条件进行任何插入或更新

时间:2012-03-11 13:46:03

标签: sql oracle plsql sqlplus

我有两张桌子 -

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

我想创建一个触发器,确保12月份无法在墨西哥购买sony talk mobile。这意味着每当我尝试在ID为3且purchase_date为12月的移动表中插入数据时,触发器应该停下来并给出适当的信息。

我的代码是 -

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和purchase_date。 我把purchase_date给了JAN,所以在这种情况下触发器不应该触发。 我很困惑。

1 个答案:

答案 0 :(得分:7)

  1. 您的触发器是在编译错误的情况下创建的。如果在创建触发器后键入show errors,SQL * Plus将向您显示语法错误。
  2. Oracle没有DATETIME数据类型。 purchase_datemobile列的数据类型必须为DATE
  3. 一旦我更正了定义mobile表的错误
  4. ,您发布的触发器在我的系统上编译并运行时没有错误
  5. 当您使用格式掩码为TO_CHAR的{​​{1}}时,结果将使用空格右边填充最长月份的长度(9个字符)。由于MONTH只有8个字符,因此您的条件永远不会评估为DECEMBER。您需要输出TRUE或使用TRIM格式掩码,该掩码不会使用空格填充输出。
  6. 这样的东西
    fmMONTH

    更有可能是你正在寻找的东西。但这并不能解释为什么你的触发器会出现编译错误。