使用PeopleSoft Query Manager提取DateTm字段年份遇ORA-01843错误
解决PeopleSoft Query Manager中提取DateTm字段年份的ORA-01843错误
问题背景
- 需从DateTm类型字段
A.SCC_ROW_ADD_DTTM提取年份(YYYY),该字段显示格式为03/19/2017 12:00:23PM - 使用表达式
TO_CHAR(TO_DATE(A.SCC_ROW_ADD_DTTM, 'MM/DD/YYYY HH:MI:SSPM'), 'YYYY')时,触发ORA-01843无效月份错误,且字段中所有月份均为01-12的两位格式 - 发现PeopleSoft Query Manager会自动将该字段转换为timestamp类型,无法手动阻止
错误原因
当前表达式存在多余且错误的类型转换逻辑:
- PeopleSoft已将DateTm字段转为timestamp类型,但你用
TO_DATE解析它,而TO_DATE的格式掩码MM/DD/YYYY HH:MI:SSPM与timestamp的默认字符串格式不匹配,导致Oracle无法识别月份,抛出ORA-01843 - 完整SQL中嵌套了多层冗余转换:
TO_CHAR(TO_DATE(TO_CHAR(CAST(A.SCC_ROW_ADD_DTTM AS TIMESTAMP),'YYYY-MM-DD-HH24.MI.SS.FF'), 'MM/DD/YYYY HH:MI:SSPM'), 'YYYY'),多层转换只会增加格式不匹配的概率
解决方案
直接对timestamp类型字段提取年份,无需额外转成date再处理,两种简单有效方法:
方法1:用EXTRACT函数提取数值型年份
EXTRACT(YEAR FROM A.SCC_ROW_ADD_DTTM)
该函数直接从timestamp(或date)类型中提取年份,返回数值类型结果,完全避免格式不匹配问题
方法2:直接用TO_CHAR处理timestamp生成字符串型年份
如果需要字符串格式的年份,直接对timestamp用TO_CHAR指定YYYY格式即可:
TO_CHAR(A.SCC_ROW_ADD_DTTM, 'YYYY')
Oracle的TO_CHAR支持直接处理timestamp类型,无需先转成date
修改后的完整SQL
将原SQL中错误的年份提取表达式替换为上述方法(以下示例用方法2):
SELECT A.ITEM_TYPE, B.DESCR, SUM(A.ITEM_AMT - A.APPLIED_AMT), TO_CHAR(A.SCC_ROW_ADD_DTTM, 'YYYY'), TO_CHAR(CAST(A.SCC_ROW_ADD_DTTM AS TIMESTAMP), 'YYYY-MM-DD-HH24.MI.SS.FF') FROM PS_ITEM_SF A, PS_ITEM_TYPE_TBL B WHERE (B.ITEM_TYPE = A.ITEM_TYPE AND (A.ITEM_TYPE IN ('600000050010','600000050020','600000050030') AND B.EFFDT = (SELECT MAX(B_ED.EFFDT) FROM PS_ITEM_TYPE_TBL B_ED WHERE B.SETID = B_ED.SETID AND B.ITEM_TYPE = B_ED.ITEM_TYPE AND B_ED.EFFDT <= SYSDATE) )) GROUP BY A.ITEM_TYPE, B.DESCR, TO_CHAR(A.SCC_ROW_ADD_DTTM, 'YYYY'), A.SCC_ROW_ADD_DTTM HAVING (SUM(A.ITEM_AMT - A.APPLIED_AMT) > 0) ORDER BY 1
注意事项
- PeopleSoft中DateTm字段本质是datetime类型,Query Manager自动转成timestamp是正常行为,无需强行阻止
- 避免对日期/时间类型做不必要的字符串转换,直接用日期函数处理原生类型是最可靠的方式
内容的提问来源于stack exchange,提问作者cody johnson
相关产品推荐
相关产品推荐

