Oracle触发器无效

时间:2012-07-19 20:49:43

标签: database oracle triggers plsql

我是SQL的新手,我正在尝试创建一个插入审计表的触发器。

create or replace trigger late_ship_insert
  after insert on suborder
  for each row
declare
  employee int;
begin
  select emp_id 
    into employee
    from handles
   where order_no = :new.order_no;
  if :new.actual_ship_date > :new.req_ship_date then
    insert into ship_audit
      values (employee, :new.order_no, :new.suborder_no, :new.req_ship_date, :new.actual_ship_date);
end;

错误:

Warning: execution completed with warning
trigger late_ship_insert Compiled.

但是一旦我尝试了一个insert语句,它告诉我触发器没有用它来删除它。

Error starting at line 1 in command:
insert into suborder 
    values  ( 8, 3, '10-jun-2012', '12-jul-2012', 'CVS', 3) 
Error at Command Line:1 Column:12
Error report:
SQL Error: ORA-04098: trigger 'COMPANY.LATE_SHIP_INSERT' is invalid and failed re-validation
04098. 00000 -  "trigger '%s.%s' is invalid and failed re-validation"
*Cause:    A trigger was attempted to be retrieved for execution and was
           found to be invalid.  This also means that compilation/authorization
           failed for the trigger.
*Action:   Options are to resolve the compilation/authorization errors,
           disable the trigger, or drop the trigger.

任何想法导致这一点,任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:3)

格式化代码时出现的错误是IF语句缺少END IF

create or replace trigger late_ship_insert
  after insert on suborder
  for each row
declare
  employee int;
begin
  select emp_id 
    into employee
    from handles
   where order_no = :new.order_no;
  if :new.actual_ship_date > :new.req_ship_date then
    insert into ship_audit
      values (employee, :new.order_no, :new.suborder_no, :new.req_ship_date, :new.actual_ship_date);
  end if;
end;

作为一般事项,您应始终在INSERT语句中列出目标表的列,而不是依赖于INSERT语句为每列指定值并在其中指定它们的事实正确的顺序。这将使您的代码更加健壮,因为当有人向表中添加其他列时它不会变得无效。这看起来像这样(我猜的是ship_audit表中列的名称)

create or replace trigger late_ship_insert
  after insert on suborder
  for each row
declare
  employee int;
begin
  select emp_id 
    into employee
    from handles
   where order_no = :new.order_no;
  if :new.actual_ship_date > :new.req_ship_date then
    insert into ship_audit( emp_id, order_no, suborder_no, req_ship_date, actual_ship_date )
      values (employee, :new.order_no, :new.suborder_no, :new.req_ship_date, :new.actual_ship_date);
  end if;
end;