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



我有两个表——

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手机不能在12月购买。这意味着每当我试图在手机表中插入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. 创建触发器时出现编译错误。如果在创建触发器后键入show errors,SQL*Plus将向您显示语法错误
  2. Oracle没有DATETIME数据类型。mobile中的purchase_date列的数据类型将需要是DATE
  3. 一旦我更正了定义mobile表时的错误,您发布的触发器就会在我的系统上编译并运行,不会出现错误
  4. 当使用格式掩码为MONTHTO_CHAR时,结果将用空格填充到最长月份的长度(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; 

更可能是你想要的。但这并不能解释为什么您的触发器会出现编译错误。

最新更新