Search code examples
oracleplsql

execution fails but I could not understand why


declare
l_statement varchar2(2000);

date2 date:= to_date('29-02-2024','dd-mm-yyyy');

begin
l_statement := 'delete from employee_tab where id=125 and joined_date =' || date2;
execute immediate l_statement;

exception 
when others then
raise;

end;
/

Error report -

ORA-00933: SQL command not properly ended
ORA-06512: at line 12
ORA-06512: at line 8
00933. 00000 -  "SQL command not properly ended"
*Cause:    
*Action:

Solution

  • That's because statement you're executing is invalid.

    Sample data:

    SQL> CREATE TABLE employee_tab
      2  AS
      3     SELECT 125 id, DATE '2024-02-29' joined_date FROM DUAL
      4     UNION ALL
      5     SELECT 555, TRUNC (SYSDATE) FROM DUAL;
    
    Table created.
    
    SQL> set serveroutput on
    

    Instead of executing it blindly, I'm displaying the statement:

    SQL> DECLARE
      2     l_statement  VARCHAR2 (2000);
      3
      4     date2        DATE := TO_DATE ('29-02-2024', 'dd-mm-yyyy');
      5  BEGIN
      6     l_statement := 'delete from employee_tab where id=125 and joined_date =' || date2;
      7
      8     DBMS_OUTPUT.put_Line (l_statement);
      9  --   EXECUTE IMMEDIATE l_statement;
     10  EXCEPTION
     11     WHEN OTHERS
     12     THEN
     13        RAISE;
     14  END;
     15  /
    delete from employee_tab where id=125 and joined_date =29.02.24
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    Can you run it? Nope:

    SQL> delete from employee_tab where id=125 and joined_date =29.02.24;
    delete from employee_tab where id=125 and joined_date =29.02.24
                                                                *
    ERROR at line 1:
    ORA-00933: SQL command not properly ended
    
    
    SQL>
    

    Don't concatenate date value; bind it.

    Sample data (once again):

    SQL> alter session set nls_date_format = 'dd.mm.yyyy';
    
    Session altered.
    
    SQL> select * From employee_tab;
    
            ID JOINED_DAT
    ---------- ----------
           125 29.02.2024
           555 19.06.2024
    

    Your new code; pay attention to EXECUTE IMMEDIATE!

    SQL> DECLARE
      2     l_statement  VARCHAR2 (2000);
      3
      4     date2        DATE := TO_DATE ('29-02-2024', 'dd-mm-yyyy');
      5  BEGIN
      6     l_statement := 'delete from employee_tab where id=125 and joined_date = :a';
      7
      8     EXECUTE IMMEDIATE l_statement
      9        USING date2;
     10  EXCEPTION
     11     WHEN OTHERS
     12     THEN
     13        RAISE;
     14  END;
     15  /
    
    PL/SQL procedure successfully completed.
    

    Result:

    SQL> select * from employee_tab;
    
            ID JOINED_DAT
    ---------- ----------
           555 19.06.2024
    
    SQL>
    

    Right; row has been deleted.