oracle Sql中有多个timestamps列,现在想要将12小时格式时间转换为24小时格式时间,如01-FEB-18 01.00.21.645000000 PM应该是05-01-0018 13:12:44。但我需要将小时数转换为24小时时间格式,我使用下面的语句。
SELECT TO_CHAR(TO_DATE(PERFORMED_TIMESTAMP,'DD-MON-YYYY hh:mi:ss AM'),'DD-MM-YYYY hh24:mi:ss')
FROM FACT_WORK_ITEM_ACTION
WHERE TRUNC(PERFORMED_TIMESTAMP)>= '05-JUN-18'
但我仍然得到以下错误。
错误代码....
ORA-01855: AM/A.M. or PM/P.M. required 01855. 00000 - "AM/A.M. or PM/P.M. required" *Cause: *Action:
答案 0 :(得分:0)
您的PERFORMED_TIMESTAMP
已经是一个时间戳,它没有任何内在的人类可读格式 - Oracle在存储值时使用自己的内部表示。
您只是看到客户端显示的时间戳,其格式取自会话NLS设置(或者,可能由客户端本身覆盖)。
错误是因为您正在进行不必要的数据类型转换,并依赖于隐式转换和NLS会话设置。当你这样做
TO_DATE(PERFORMED_TIMESTAMP,'DD-MON-YYYY hh:mi:ss AM')
您首先使用会话NLS设置隐式地将PERFORMED_TIMESTAMP
转换为字符串,因此您可以有效地执行此操作:
TO_DATE(TO_CHAR(PERFORMED_TIMESTAMP),'DD-MON-YYYY hh:mi:ss AM')
给出了问题中的字符串值实际上是:
TO_DATE(TO_CHAR(PERFORMED_TIMESTAMP, 'DD-MON-RR HH.MI.SS.FF AM'),'DD-MON-YYYY hh:mi:ss AM')
它的内部部分将提供类似“01-FEB-18 01.00.21.645000000 PM”的字符串,这是您在查询表时看到的,并且客户端执行自己的格式化。将该字符串传递回to_date()
会给出您看到的错误,因为小数秒出现在字符串中,它希望看到AM / PM标记:
SELECT TO_DATE('01-FEB-18 01.00.21.645000000 PM','DD-MON-YYYY hh:mi:ss AM')
FROM DUAL;
Error report -
ORA-01855: AM/A.M. or PM/P.M. required
你可以用显式转换和格式掩码替换implcit转换和会话值:
TO_CHAR(TO_DATE(TO_CHAR(PERFORMED_TIMESTAMP, 'DD-MON-YYYY hh:mi:ss AM'),'DD-MON-YYYY hh:mi:ss AM'), 'DD-MM-YYYY hh24:mi:ss')
但是希望你能说它做的工作比它需要做的多得多 - 并且必须两次使用相同的格式掩码也表明你做错了。
真正的解决方案就是简化它。您根本不需要转换为字符串并返回日期。只是做:
SELECT TO_CHAR(PERFORMED_TIMESTAMP, 'DD-MM-YYYY HH24:MI:SS')
FROM FACT_WORK_ITEM_ACTION
WHERE PERFORMED_TIMESTAMP >= TIMESTAMP '2018-06-05 00:00:00';
请注意,我还删除了trunc()
以及与字符串的比较;现在,这将您的时间戳列作为时间戳进行比较,这将使任何索引更快乐。
使用CTE进行快速演示以提供虚拟数据:
with FACT_WORK_ITEM_ACTION(PERFORMED_TIMESTAMP) as (
select timestamp '2018-06-01 13:00:21.645000000' from dual
union all select timestamp '2018-06-06 13:00:21.645000000' from dual
)
SELECT TO_CHAR(PERFORMED_TIMESTAMP, 'DD-MM-YYYY HH24:MI:SS')
FROM FACT_WORK_ITEM_ACTION
WHERE PERFORMED_TIMESTAMP >= TIMESTAMP '2018-06-05 00:00:00';
TO_CHAR(PERFORMED_T
-------------------
06-06-2018 13:00:21
答案 1 :(得分:0)
SELECT to_char(TO_timestamp('01-FEB-18 01.21.01.645','dd-mon-yy hh12.mi.ss.ff'),'dd-mm-yyyy hh24:mi:ss') 来自双重;