ORACLE - ORA-01843: 不是一个有效的月份
Posted
技术标签:
【中文标题】ORACLE - ORA-01843: 不是一个有效的月份【英文标题】:ORACLE - ORA-01843: not a valid month 【发布时间】:2016-03-08 14:03:58 【问题描述】:我更改了 php 的 OCI8 版本,因为这个查询不起作用:
SELECT 'M'||to_char(to_date(OD.DATE2,'DD/MM/YYYY'),'MM') PERIODE, count(*) DATA, OD.DCCPT DCCPT
FROM BDD OD
WHERE BDD = 'phone'
AND OD.SENS = 'Ent'
AND OD.DCCPT IN('PIOLUC')
AND (OD.DATE2 BETWEEN '08/03/2015' AND '08/03/2016')
group by 'M'||to_char(to_date(OD.DATE2,'DD/MM/YYYY'),'MM'), OD.CDCCPT CDCCPT
我收到了这条消息:
消息:oci_execute(): ORA-01843: not a valid month
它适用于 Toad for Oracle 11。您有什么解决方案吗?
谢谢你:)
【问题讨论】:
DATE2的数据类型是什么? 如果date2
是date
那么为什么要使用to_date()
将date
转换为date
值?
您在GROUP BY
中有一个错误的别名,并且您按CDCCPT
分组,但您选择的列是DCCPT
。您可能也想解决这些问题。
【参考方案1】:
看线:
OD.DATE2 BETWEEN '08/03/2015' AND '08/03/2016'
那么'08/03/2015'
和'08/03/2016'
是字符串文字,不是日期。
Oracle 将尝试使用您的 NLS_DATE_FORMAT
会话参数作为格式掩码从字符串文字到日期的隐式转换,如果这不起作用,它将引发错误。
简单的解决方案是不使用字符串文字,而是使用日期文字:
SELECT 'M'||to_char( DATE2, 'MM' ) PERIODE,
count(*) DATA,
DCCPT
FROM BDD
WHERE BDD = 'phone'
AND SENS = 'Ent'
AND DCCPT IN ( 'PIOLUC' )
AND DATE2 BETWEEN DATE '2015-03-08' AND DATE '2016-03-08'
GROUP BY
'M'||to_char( DATE2, 'MM' ),
DCCPT
但您也可以指定格式掩码:
OD.DATE2 BETWEEN TO_DATE( '08/03/2015', 'DD/MM/YYYY' ) AND TO_DATE( '08/03/2016', 'DD/MM/YYYY' )
【讨论】:
【参考方案2】:假设OD.DATE2
是DATE 数据类型,您需要将日期字符串(例如'08/03/2015'
)显式转换为日期格式。
类似:
SELECT 'M'||to_char(OD.DATE2,'MM') PERIODE,
count(*) DATA,
OD.DCCPT DCCPT
FROM BDD OD
WHERE BDD = 'phone'
AND OD.SENS = 'Ent'
AND OD.DCCPT IN ('PIOLUC')
AND OD.DATE2 BETWEEN to_date('08/03/2015', 'dd/mm/yyyy') AND to_date('08/03/2016', 'dd/mm/yyyy')
group by 'M'||to_char(OD.DATE2,'MM'),
OD.DCCPT;
请注意我是如何在 select 和 group by 列表中从 OD.DATE2
周围删除 to_date
的,因为将 to_date
用于已经是日期。
通过这样做,您强制 Oracle 对字符串进行隐式转换,它会通过使用您的 NLS_DATE_FORMAT 参数来决定输出字符串的格式,然后再尝试将其转换回日期使用您指定的格式掩码,如下所示:
to_date(to_char(od.date2, '<nls_date_format parameter>'), 'DD/MM/YYYY')
如果两个格式掩码不相同,您将遇到错误...例如提示您发布此问题的那个!
【讨论】:
工作就像一个魅力,我应该看到它..谢谢!以上是关于ORACLE - ORA-01843: 不是一个有效的月份的主要内容,如果未能解决你的问题,请参考以下文章
ORA-01843 - 不是有效的月份 oracle SQL