Search code examples
sqloracle-databaseplsqloracle-sqldeveloperplsqldeveloper

My PL/SQL procedure exception doesn't seem to work


I have a database with continents and I wanted to create a procedure that added a new continent to the database, with exceptions. I tried executing the procedure inside my package GEST_GEO by creating an already existing continent (Asia) and my exception was not raised. Does anyone have any idea that to why it doesn't work ? (nom is name)

Here is my code :

CREATE OR REPLACE PACKAGE GEST_GEO AS
Procedure ADDCONTINENT(pnom continent.nom%TYPE, psuperficie continent.superficie%TYPE);
END GEST_GEO;
/

CREATE OR REPLACE PACKAGE BODY GEST_GEO AS

-- ADDCONTINENT

Procedure ADDCONTINENT(pnom CONTINENT.NOM%TYPE, psuperficie CONTINENT.SUPERFICIE%TYPE) IS
BEGIN
    INSERT INTO CONTINENT VALUES (pnom, psuperficie);
COMMIT;
EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('The continent already exists');
    WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE || '–' || SQLERRM);

END ADDCONTINENT;
END GEST_GEO;
/


execute GEST_GEO.ADDCONTINENT('Asia',99380);

When executing it it just tells me PL/SQL procedure successfully completed

Thank you


Solution

  • DUP_VAL_ON_INDEX presumes that there's a primary or unique key, or unique index enforced on that column. If there's none, Oracle doesn't know that there's anything "duplicated" so it inserts a row.

    Therefore, create something of previously mentioned (keys/indexes).


    Here's an example: table first (note the primary key constraint in line #2):

    SQL> create table continent
      2    (nom         varchar2(30) constraint pk_cont primary key,
      3     superficie  number
      4    );
    
    Table created.
    

    Procedure: note

    • line #5 - always include target column names in INSERT statement
    • exception handler section: don't output the message - unless tool you use supports it, buffer's contents won't be visible to anyone. RAISE the error instead
    • don't commit within the procedure; let the caller decide whether to commit or not

    So:

    SQL> create or replace procedure addcontinent
      2    (pnom continent.nom%type, psuperficie continent.superficie%type)
      3  is
      4  begin
      5    insert into continent (nom, superficie) values (pnom, psuperficie);
      6  exception
      7    when dup_val_on_index then
      8      raise_application_error(-20001, 'The continent already exists');
      9    when others then
     10      raise;
     11  end addcontinent;
     12  /
    
    Procedure created.
    

    Testing:

    SQL> exec addcontinent('Asia', 99380);
    
    PL/SQL procedure successfully completed.
    
    SQL> exec addcontinent('Asia', 99380);
    BEGIN addcontinent('Asia', 99380); END;
    
    *
    ERROR at line 1:
    ORA-20001: The continent already exists
    ORA-06512: at "SCOTT.ADDCONTINENT", line 8
    ORA-06512: at line 1
    
    
    SQL> select * from continent;
    
    NOM                            SUPERFICIE
    ------------------------------ ----------
    Asia                                99380
    
    SQL>