简体   繁体   English

使用日期值执行IN参数过程时,这不是有效月份

[英]Not a valid month when executing an IN parameter procedure with date value

CREATE OR REPLACE PROCEDURE PROC1(
   V_STARTTIME    IN TIMESTAMP ,
   V_ENDTIME      IN TIMESTAMP )
BEGIN
INSERT INTO TAB1
SELECT COINS FROM TAB2
WHERE DATE BETWEEN TO_DATE(V_STARTTIME,'mm/dd/yyyy hh:mi:ss aM') AND TO_DATE(V_ENDTIME    ,'mm/dd/yyyy hh:mi:ss aM');
END;

SAMPLE DATE in Tab2 5/5/2014 9:46:38.000000 AM

My script runs between a range of dates. 我的脚本在一系列日期之间运行。 The two dates are IN parameters. 这两个日期是IN参数。

When I execute the procedure 当我执行程序时

Execute proc1('5/05/2014 11:25:00 AM','5/05/2014 12:25:00 PM') 执行proc1('5/05/2014 11:25:00 AM','5/05/2014 12:25:00 PM')

I am getting not a valid month error. 我没有收到有效的月份错误。 Any idea how to fix this? 知道如何解决这个问题吗? Thanks 谢谢

Your procedure takes parameters of type timestamp . 您的过程采用timestamp类型的参数。 You're actually passing parameters of type varchar2 in your call. 您实际上是在调用中传递varchar2类型的参数。 That forces Oracle to perform implicit conversion of the varchar2 parameters to timestamp using your session's NLS_TIMESTAMP_FORMAT . 这迫使Oracle使用会话的NLS_TIMESTAMP_FORMATvarchar2参数隐式转换为timestamp That will likely be different for different sessions so it is likely that at least some sessions will get an error because the string doesn't match the format of that session's NLS_TIMESTAMP_FORMAT . 对于不同的会话,这可能会有所不同,因此至少某些会话可能会出错,因为该字符串与该会话的NLS_TIMESTAMP_FORMAT格式不匹配。 You'd be much better served passing in an actual timestamp either by explicitly calling to_timestamp or by passing a timestamp literal. 通过显式调用to_timestamp或传递时间戳文字来传递实际时间戳会更好。

Your procedure then takes the timestamp parameters and pass them to the to_date function. 然后,您的过程将获取timestamp参数并将它们传递给to_date函数。 The to_date function does not take parameters of type timestamp , it only takes parameters of type varchar2 . to_date函数不接受timestamp类型的参数,它只接受varchar2类型的参数。 That forces Oracle to do another implicit conversion of the timestamp parameters to varchar2 , again using the session's NLS_TIMESTAMP_FORMAT . 这迫使Oracle再次使用会话的NLS_TIMESTAMP_FORMATtimestamp参数隐式转换为varchar2 If the session's NLS_TIMESTAMP_FORMAT doesn't match the explicit format mask in your to_date call, you'll get an error or the conversion will return a result that you don't expect. 如果会话的NLS_TIMESTAMP_FORMATto_date调用中的显式格式掩码不匹配,则会出现错误或转换将返回您不期望的结果。

If the column in your table is actually of type date , you can directly compare a date to a timestamp . 如果表中的列实际上是date类型,则可以直接将datetimestamp进行比较。 So there doesn't appear to be any reason to call to_date here. 所以似乎没有任何理由在这里调用to_date Based on your sample data, though, it appears that the column in your table is actually of type timestamp rather than date as your code implies, since a date does not have fractional seconds of precision. 根据您的样本数据,不过,看来在你的表中的列实际上是类型的timestamp ,而不是date为您的代码意味着,由于date不具有精度小数秒。 If that's the case, it makes even less sense to call to_date in your SELECT statement since your parameters are actually of type timestamp and your column is of type timestamp . 如果是这种情况,那么在SELECT语句中调用to_date意义了,因为你的参数实际上是timestamp类型,而你的列的类型是timestamp Just compare the timestamp values. 只需比较timestamp值。

My guess, therefore, is that you want something like 因此,我的猜测是你需要类似的东西

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;

and that you want to cal the procedure by passing actual timestamps. 并且您希望通过传递实际时间戳来调用该过程。 Using timestamp literals 使用时间戳文字

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

or by explicitly calling to_timestamp 或者通过显式调用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' ) );

That should get rid of all the implicit type conversions that are currently taking place. 这应该摆脱目前正在发生的所有隐式类型转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM