use*_*319 1 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');
Run Code Online (Sandbox Code Playgroud)
我想创建一个触发器,以确保在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;
Run Code Online (Sandbox Code Playgroud)
触发器已创建,但当我尝试使用此代码插入此数据时 -
insert into mobile values('3','Sony Talk','10-JAN-11');
Run Code Online (Sandbox Code Playgroud)
触发器触发但出错 -
ORA-04098: trigger 'OPS$0924769.TRG1' is invalid and failed re-validation
Run Code Online (Sandbox Code Playgroud)
而我的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;
Run Code Online (Sandbox Code Playgroud)
它没有检查id和purchase_date.我把purchase_date给了JAN,所以在这种情况下触发器不应该触发.我很迷惑.
show errors在创建触发器后键入,SQL*Plus将向您显示语法错误.DATETIME数据类型.purchase_date列的数据类型mobile必须是a DATE.mobile表中的错误,您发布的触发器就会在我的系统上编译并运行而不会出现错误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;
Run Code Online (Sandbox Code Playgroud)
你想要的更有可能.但这并不能解释为什么你的触发器会出现编译错误.