Oracle
 sql >> база данни >  >> RDS >> Oracle

Не е валиден месец при изпълнение на процедура на IN параметър със стойност на датата

Вашата процедура приема параметри от тип timestamp . Вие всъщност предавате параметри от тип varchar2 във вашето обаждане. Това принуждава Oracle да извърши имплицитно преобразуване на varchar2 параметри на timestamp използвайки NLS_TIMESTAMP_FORMAT на вашата сесия . Това вероятно ще бъде различно за различните сесии, така че е вероятно поне някои сесии да получат грешка, защото низът не съвпада с формата на NLS_TIMESTAMP_FORMAT на тази сесия . Ще бъдете много по-добре да подадете действително времево клеймо или чрез изрично извикване на to_timestamp или чрез предаване на литерал на времево клеймо.

След това вашата процедура взема timestamp параметри и ги предава на to_date функция. to_date функцията не приема параметри от тип timestamp , той приема само параметри от тип varchar2 . Това принуждава Oracle да направи друго имплицитно преобразуване на timestamp параметри към varchar2 , отново използвайки NLS_TIMESTAMP_FORMAT на сесията . Ако NLS_TIMESTAMP_FORMAT на сесията не съвпада с изричната маска за формат във вашия to_date повикване, ще получите грешка или преобразуването ще върне резултат, който не очаквате.

Ако колоната във вашата таблица всъщност е от тип date , можете директно да сравните date към timestamp . Така че изглежда няма причина да се извиква to_date тук. Въз основа на вашите примерни данни обаче изглежда, че колоната във вашата таблица всъщност е от тип timestamp вместо date както предполага вашият код, от date няма дробни секунди с точност. Ако случаят е такъв, има още по-малко смисъл да се извиква to_date във вашия SELECT тъй като вашите параметри всъщност са от тип timestamp и вашата колона е от тип timestamp . Просто сравнете timestamp стойности.

Следователно моето предположение е, че искате нещо като

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;

и че искате да извикате процедурата чрез предаване на действителни времеви отпечатъци. Използване на литерали за клеймо за време

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

или чрез изрично извикване на 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' ) );

Това трябва да премахне всички неявни преобразувания на типове, които се извършват в момента.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как бързо да изберете данни от Oracle

  2. Как да използвате променливи в клауза where на Oracle PL/SQL

  3. ORA-12154 не можа да разреши посочения идентификатор за свързване

  4. Как да използвате клауза за групово събиране с оператор SELECT INTO в базата данни на Oracle

  5. Oracle PL/SQL - Как да създадете обикновена променлива от масив?