Oracle
 sql >> Database >  >> RDS >> Oracle

Mese non valido durante l'esecuzione di una procedura di parametro IN con valore di data

La tua procedura accetta parametri di tipo timestamp . Stai effettivamente passando parametri di tipo varchar2 nella tua chiamata. Ciò costringe Oracle a eseguire la conversione implicita di varchar2 parametri su timestamp utilizzando il NLS_TIMESTAMP_FORMAT della tua sessione . Probabilmente sarà diverso per sessioni diverse, quindi è probabile che almeno alcune sessioni ricevano un errore perché la stringa non corrisponde al formato di NLS_TIMESTAMP_FORMAT di quella sessione . Sarebbe molto più utile passare un timestamp effettivo chiamando esplicitamente to_timestamp o passando un valore letterale di timestamp.

La tua procedura prende quindi il timestamp parametri e passarli a to_date funzione. Il to_date la funzione non accetta parametri di tipo timestamp , accetta solo parametri di tipo varchar2 . Ciò costringe Oracle a eseguire un'altra conversione implicita del timestamp parametri a varchar2 , sempre utilizzando il NLS_TIMESTAMP_FORMAT della sessione . Se la sessione è NLS_TIMESTAMP_FORMAT non corrisponde alla maschera di formato esplicito nel tuo to_date chiama, riceverai un errore o la conversione restituirà un risultato che non ti aspetti.

Se la colonna nella tabella è effettivamente di tipo date , puoi confrontare direttamente una date a un timestamp . Quindi non sembra esserci alcun motivo per chiamare to_date qui. In base ai tuoi dati di esempio, tuttavia, sembra che la colonna nella tabella sia in realtà di tipo timestamp anziché date come suggerisce il tuo codice, poiché una date non ha secondi frazionari di precisione. Se è così, ha ancora meno senso chiamare to_date nel tuo SELECT istruzione poiché i tuoi parametri sono in realtà di tipo timestamp e la tua colonna è di tipo timestamp . Basta confrontare il timestamp valori.

La mia ipotesi, quindi, è che tu voglia qualcosa come

CREATE OR REPLACE PROCEDURE PROC1(
   V_STARTTIME    IN TIMESTAMP ,
   V_ENDTIME      IN TIMESTAMP )
BEGIN
  INSERT INTO TAB1( <<column name>> )
    SELECT COINS 
      FROM TAB2
     WHERE <<timestamp column name>> BETWEEN v_starttime AND v_endtime;
END;

e che vuoi chiamare la procedura passando i timestamp effettivi. Utilizzo di valori letterali timestamp

Execute proc1(timestamp '2014-05-05 11:25:00', timestamp '2014-05-05 12:25:00' )

o chiamando esplicitamente to_timestamp

execute proc1( to_timestamp( '5/05/2014 11:25:00 AM', 'MM/DD/YYYY HH:MI:SS AM' ),
               to_timestamp( '5/05/2014 12:25:00 PM', 'MM/DD/YYYY HH:MI:SS AM' ) );

Ciò dovrebbe eliminare tutte le conversioni di tipo implicite attualmente in corso.