奇怪的TO_DATE和SQLPLUS行为

时间:2015-11-04 10:39:42

标签: sql oracle type-conversion to-date

我有一个提供SYSDATE的查询和来自配置文件的硬编码时间值。

select request_rrn||','||transfer_id||','||
client_id||','||src_fund_acct_id||','||
tgt_fund_acct_id||','||
to_char((timestamp + 8/24), 'MON-DD-YYYY HH24:MI:SS')||','||
txn_amount||','||se_respcode
from mi3_txn_logs 
where client_id = 'test'
and (timestamp + 8/24) between to_date(trunc((SYSDATE + 8/24) - 7)||' 08:00:00', 'MM/DD/YYYY HH24:MI:SS')
and to_date(trunc((SYSDATE + 8/24) - 0)||' 07:59:59', 'MM/DD/YYYY HH24:MI:SS')
order by logtime desc;

当我在sqldeveloper中执行此查询时,它可以正常工作。 (我认为)。但是当我在sqlplus中运行它时,我收到此错误

and to_date(trunc((SYSDATE + 8/24) - 0)||' 07:59:59', 'MM/DD/YYYY HH24:MI:SS')
                                        *
ERROR at line 10:
ORA-01858: a non-numeric character was found where a numeric was expected

这是我通过SQLPLUS执行的完整SQL文件:

SET TRIMSPOOL ON;
SET HEADING OFF FEEDBACK OFF TERMOUT OFF ECHO OFF PAGESIZE 50000 LINESIZE 238 WRAP OFF;
SPOOL /home/ec2-user/out.csv;
select request_rrn||','||transfer_id||','||
client_id||','||src_fund_acct_id||','||
tgt_fund_acct_id||','||
to_char((timestamp + 8/24), 'MON-DD-YYYY HH24:MI:SS')||','||
txn_amount||','||se_respcode
from mi3_txn_logs 
where client_id = 'test'
and (timestamp + 8/24) between to_date(trunc((SYSDATE + 8/24) - 1)||' 08:00:00', 'MM/DD/YYYY HH24:MI:SS')
and to_date(trunc((SYSDATE + 8/24) - 0)||' 07:59:59', 'MM/DD/YYYY HH24:MI:SS')
order by logtime desc;
SPOOL OFF;
quit

我认为我的SYSDATE和硬编码时间连接有问题。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您在此处嵌套隐式数据类型转换。

部分to_date(trunc((SYSDATE + 8/24) - 0)会使用当前的NLS设置将trunc((SYSDATE + 8/24)的结果 - DATE - 转换为VARCHAR,然后转换VARCHAR }回到DATE - 它开头。

您需要将“截断”日期转换为格式正确的VARCHAR然后to_date()应用于连接结果。

to_date(to_char(trunc(SYSDATE + 8/24), 'MM/DD/YYYY')||' 07:59:59', 'MM/DD/YYYY HH24:MI:SS')

(我删除了- 0以减少表达式中的噪音并减少括号)

您还需要将其应用于其他表达式

无关,但是:我更喜欢使用适当的间隔来提高可读性:

timestamp + interval '8' hour代替timestamp + 8/24