2012-07-19 3 views
2

Je suis nouveau dans SQL et j'essaie de créer un déclencheur qui serait inséré dans une table d'audit.Déclencheur Oracle invalide

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; 

Erreur:

Warning: execution completed with warning 
trigger late_ship_insert Compiled. 

Mais une fois que je tente une déclaration d'insertion, il me dire la gâchette ne fonctionne pas pour le laisser tomber.

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. 

Une idée de ce qui cause, toute aide serait grandement appréciée. Merci!

+1

Faites un SHOW ERRORS' après avoir créé la gâchette et nous montrer le message d'erreur. –

+1

Je serais surpris de trouver le type 'int' dans Oracle ... Essayez numéro? –

+1

Je pense qu'il vous manque un 'END IF;' plus, je pense que toutes les variables 'déclaré' devraient être placées au début. – alfasin

Répondre

3

L'erreur qui apparaît lorsque vous formatez votre code est que votre déclaration IF manque le 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; 

En général, vous devriez toujours énumérer les colonnes du tableau de destination dans votre lieu déclaration INSERT que de compter sur le fait que votre instruction INSERT spécifie une valeur pour chaque colonne et les spécifie dans le bon ordre. Cela rendra votre code beaucoup plus robuste car il ne deviendra pas invalide lorsque quelqu'un ajoutera des colonnes supplémentaires à la table par exemple. Cela ressemblerait à quelque chose comme ça (je devine les noms des colonnes dans le tableau 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

yeps, je le pense aussi. +1 – alfasin

+0

Je vois, merci beaucoup l'explication c'était vraiment utile! – JProg

Questions connexes