2012-07-19 113 views
2

我是新来的SQL,我试图创建一个插入到审计表的触发器。Oracle触发无效

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

做一个'SHOW ERRORS'创建触发器和告诉我们错误消息后。 – 2012-07-19 20:51:37

+1

我会惊讶地发现Oracle中的int类型...尝试编号? – 2012-07-19 20:52:06

+1

我认为你错过了'END IF;'plus,我认为所有的'声明'变量都应该放在开头。 – alfasin 2012-07-19 20:55:40

回答

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; 
+0

年,我也这么认为。 +1 – alfasin 2012-07-19 20:59:11

+0

我看到了,非常感谢你的解释,它真的有帮助! – JProg 2012-07-19 21:06:05