我有两个表——
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,所以在这种情况下,触发器不应该触发。我很困惑。
- 创建触发器时出现编译错误。如果在创建触发器后键入
show errors
,SQL*Plus将向您显示语法错误 - Oracle没有
DATETIME
数据类型。mobile
中的purchase_date
列的数据类型将需要是DATE
- 一旦我更正了定义
mobile
表时的错误,您发布的触发器就会在我的系统上编译并运行,不会出现错误 - 当使用格式掩码为
MONTH
的TO_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;
更可能是你想要的。但这并不能解释为什么您的触发器会出现编译错误。