2012-07-19 120 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