PL / SQL TRIGGER编译错误

时间:2014-03-31 21:04:26

标签: oracle plsql triggers syntax-error

create or replace trigger enroll_bef_ins_row
before insert on enrollments
for each row
declare
original            number;
seatsremain_already_full    exception;
begin

Select seatsremain into original from offering where offerno= :new.offerno;
if original > 0 then
    update offering set seatsremain= seatsremain - 1;
    dmbs_output.put_line ('Seats available in offering' |offerno| 'have decreased from' |:old.seatsremain| to |:new.seatsremain|);
else if original = 0 then
    dbms_output.put_line ('Offering' |offerno| 'is already full!');
    raise seatsremain_already_full 
end if;
exception
when seatsremain_already_full
    raise_application_error (-20001, 'Cannot allow insertion');
end
/

我不断收到“使用编译错误创建的触发器”消息,每次我尝试插入值时,我都会收到ORA 04098 - SYSTEM.ENROLL_BEFORE_INS_ROW是无效且失败的REVALIDATION消息。

我的任务是编写一个触发器,在将一行插入注册表之前执行以下任务:

如果座位可用于特定产品,触发器应自动减少产品的座位数量并显示消息:提供的可用座位(提供号码)已从(插入前可用的座位数)减少到(插入后可用的座位数)。如果插入后可用的座位数等于0,则显示消息:'不再提供座位(此处应提供提供号码)

如果在注册中插入行之前,特定产品的可用座位等于0,则触发器应显示以下内容:

不允许插入

并使用raise_application_error过程来阻止执行INSERT语句

1 个答案:

答案 0 :(得分:0)

连接运算符为||,所有语句必须以分号结尾。还有一个奇怪的撇号在这里和那里失踪。

试试这个:

create or replace trigger enroll_bef_ins_row
  before insert on enrollments
  for each row
declare
  original                    number;
  seatsremain_already_full    exception;
begin
  Select seatsremain
    into original
    from offering
    where offerno = :new.offerno;

  if original > 0 then
    update offering
      set seatsremain = seatsremain - 1
      WHERE OFFERNO = :new.OFFERNO;

    dmbs_output.put_line ('Seats available in offering' || :new.offerno ||
                          'have decreased from' || original ||
                          ' to ' || original-1);
  elsif original = 0 then
    dbms_output.put_line ('Offering' || offerno ||
                          ' is already full!');
    raise seatsremain_already_full;
  end if;
exception
  when seatsremain_already_full
    raise_application_error (-20001, 'Cannot allow insertion');
end;

我建议您可能不想减少SEATSREMAIN,而是通过取得OFFERING.SEATSAVAILABLE并减去所占座位总和来计算剩余座位数 - 否则在OFFERING.SEATSREMAIN上有一个竞争条件你可以结束过度预订 - 但这可能适用于简单的案例。此外,如果SEATSREMAIN结束为负,您可能希望引发错误。

分享并享受。