Search code examples
sqloracle-databaseoracle9i

Keyword 'Values' absent Oracle 9i


I'm trying to execute the following trigger when inserting some data in my table :

CREATE OR REPLACE TRIGGER AJOUTER_NEW_CONSISTANCE 
   AFTER INSERT OR UPDATE OF 
     CONSISTANCE_LIBELLE_1,CONSISTANCE_LIBELLE_2,CONSISTANC_LIBELLE_3 
   ON DB.ETAT_PARCELLAIRE  
BEGIN

  insert into DB.CONSISTANCE.LIBELLE
  select consistance_libelle_1
    from DB.ETAT_PARCELLAIRE
   where DB.ETAT_PARCELLAIRE.consistance_libelle_1 not in (
        select LIBELLE from  DB.CONSISTANCE.LIBELLE);

END;  

But it keeps giving me the following error :

PL/SQL : ORA00926 : Keyword Values absent.  

How can I fix this ?
Thank you for help in advance :)


Solution

  • If CONSISTANCE is a table with a column called LIBELLE then you're referring to it incorrectly.

    • your insert is including the column, which I assume means the table has other columns and you only want to insert a value into that one, but your syntax is wrong (DB.CONSISTANCE.LIBELLE should be DB.CONSISTANCE(LIBELLE)). it is this line that's generating the ORA-00926.
    • your sub-select is including the column in the table name (DB.CONSISTANCE.LIBELLE should be just DB.CONSISTANCE)

    So it should be:

    CREATE OR REPLACE TRIGGER AJOUTER_NEW_CONSISTANCE 
       AFTER INSERT OR UPDATE OF 
         CONSISTANCE_LIBELLE_1,CONSISTANCE_LIBELLE_2,CONSISTANC_LIBELLE_3 
       ON DB.ETAT_PARCELLAIRE  
    BEGIN
    
      insert into DB.CONSISTANCE(LIBELLE)
      select consistance_libelle_1
        from DB.ETAT_PARCELLAIRE
       where consistance_libelle_1 not in (
            select LIBELLE from DB.CONSISTANCE);
    
    END;
    

    I'm also not sure if CONSISTANC_LIBELLE_3 is a typo and it should be CONSISTANCE_LIBELLE_3.

    You could also do a not exists instead of a not in:

      insert into DB.CONSISTANCE(LIBELLE)
      select CONSISTANCE_LIBELLE_1
        from DB.ETAT_PARCELLAIRE
       where not exists (
             select 1
               from DB.CONSISTANCE
              where LIBELLE = DB.ETAT_PARCELLAIRE.CONSISTANCE_LIBELLE_1
             );
    

    Or use a merge:

      merge into DB.CONSISTANCE c
      using (select CONSISTANCE_LIBELLE_1 from DB.ETAT_PARCELLAIRE) ep
      on (c.LIBELLE = ep.CONSISTANCE_LIBELLE_1)
      when not matched then
        insert (LIBELLE) values (ep.CONSISTANCE_LIBELLE_1);
    

    Using a trigger to (partially) maintain that table looks odd though - it would be simpler to have a view which selects distinct values from ETAT_PARCELLAIRE:

    create or replace view CONSISTANCE_VIEW as
    select distinct CONSISTANCE_LIBELLE_1
      from ETAT_PARCELLAIRE;
    

    But they would have different content - once a value has appeared in CONSISTANCE_LIBELLE_1 it will always remain in CONSISTANCE as you are not removing defunct values, only inserting new ones; whereas CONSISTANCE_VIEW would only show values currently in the table. It isn't clear which behaviour you want.