sql >> Databasteknik >  >> RDS >> Oracle

Inte en giltig månad vid exekvering av en IN-parameterprocedur med datumvärde

Din procedur tar parametrar av typen timestamp . Du skickar faktiskt parametrar av typen varchar2 i ditt samtal. Det tvingar Oracle att utföra implicit konvertering av varchar2 parametrar till timestamp med sessionens NLS_TIMESTAMP_FORMAT . Det kommer sannolikt att vara olika för olika sessioner så det är troligt att åtminstone vissa sessioner kommer att få ett fel eftersom strängen inte matchar formatet för sessionens NLS_TIMESTAMP_FORMAT . Du skulle vara mycket bättre tjänt av att passera i en faktisk tidsstämpel antingen genom att uttryckligen anropa to_timestamp eller genom att skicka en tidsstämpel bokstavligt.

Din procedur tar sedan timestamp parametrar och skicka dem till to_date fungera. to_date funktionen tar inte parametrar av typen timestamp , det tar bara parametrar av typen varchar2 . Det tvingar Oracle att göra ytterligare en implicit konvertering av timestamp parametrar till varchar2 , igen med sessionens NLS_TIMESTAMP_FORMAT . Om sessionens NLS_TIMESTAMP_FORMAT matchar inte den explicita formatmasken i din to_date ringer, får du ett felmeddelande eller så returnerar konverteringen ett resultat som du inte förväntar dig.

Om kolumnen i din tabell faktiskt är av typen date , kan du direkt jämföra ett date till en timestamp . Så det verkar inte finnas någon anledning att ringa to_date här. Baserat på dina exempeldata verkar det dock som om kolumnen i tabellen faktiskt är av typen timestamp istället för date som din kod antyder, eftersom ett date har inte bråkdels sekunders precision. Om så är fallet är det ännu mindre meningsfullt att anropa to_date i din SELECT uttalande eftersom dina parametrar faktiskt är av typen timestamp och din kolumn är av typen timestamp . Jämför bara timestamp värden.

Min gissning är därför att du vill ha något liknande

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;

och att du vill kalla proceduren genom att skicka faktiska tidsstämplar. Använda tidsstämpellitterals

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

eller genom att uttryckligen anropa 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' ) );

Det borde bli av med alla implicita typkonverteringar som för närvarande äger rum.




  1. Hur delar man upp kommaseparerad sträng av poster och arrangerar sedan sekventiellt i MySQL?

  2. Att använda MySQL:s TIMESTAMP kontra att lagra tidsstämplar direkt

  3. Konfigurera Master-Master MySQL-databasreplikering

  4. ORA-29908:saknad primär anrop för sidooperatör