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

Posted

技术标签:

【中文标题】在 oracle 中创建一个触发器,它不允许使用 if 条件进行任何插入或更新【英文标题】:create a trigger in oracle which will not allow any insert or update with if condition 【发布时间】:2012-03-11 13:46:02 【问题描述】:

我有两张桌子--

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】:
    您的触发器创建时出现编译错误。如果您在创建触发器后键入show errors,SQL*Plus 将向您显示语法错误。 Oracle 没有DATETIME 数据类型。 mobilepurchase_date 列的数据类型需要是 DATE。 一旦我更正了定义 mobile 表时的错误,您发布的触发器将在我的系统上编译和运行而没有错误 当您使用带有格式掩码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; 

更有可能是您要查找的内容。但这并不能解释为什么您的触发器会出现编译错误。

【讨论】:

以上是关于在 oracle 中创建一个触发器,它不允许使用 if 条件进行任何插入或更新的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 11g 中创建触发器的问题

我在 SQL Plus 中创建了触发器而没有错误,但它不起作用

在 Oracle Express 中创建触发器

在 Oracle PL/SQL 中创建触发器时如何解决“编译错误成功”错误?

在oracle中创建自动增长字段

Oracle中创建触发器示例及注意事项