您的过程采用timestamp 类型的参数。您实际上是在调用中传递 varchar2 类型的参数。这会强制 Oracle 使用会话的 NLS_TIMESTAMP_FORMAT 将 varchar2 参数隐式转换为 timestamp。对于不同的会话,这可能会有所不同,因此至少有一些会话可能会出错,因为字符串与该会话的NLS_TIMESTAMP_FORMAT 的格式不匹配。通过显式调用 to_timestamp 或传递时间戳文字,传递实际时间戳会更好。
然后您的过程接受timestamp 参数并将它们传递给to_date 函数。 to_date 函数不接受 timestamp 类型的参数,它只接受 varchar2 类型的参数。这迫使 Oracle 再次使用会话的 NLS_TIMESTAMP_FORMAT 将 timestamp 参数隐式转换为 varchar2。如果会话的NLS_TIMESTAMP_FORMAT 与to_date 调用中的显式格式掩码不匹配,您将收到错误消息,或者转换将返回您不期望的结果。
如果表中的列实际上是date 类型,则可以直接将date 与timestamp 进行比较。所以似乎没有任何理由在这里打电话给to_date。但是,根据您的示例数据,您的表中的列似乎实际上是 timestamp 类型,而不是您的代码所暗示的 date,因为 date 没有小数秒精度。如果是这种情况,在SELECT 语句中调用to_date 就更没有意义了,因为您的参数实际上是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' ) );
这应该消除当前正在发生的所有隐式类型转换。