不是有效的月份 - SQL ORA-01843 - 在 unix 中

Posted

技术标签:

【中文标题】不是有效的月份 - SQL ORA-01843 - 在 unix 中【英文标题】:Not A valid Month - SQL ORA-01843 - In unix 【发布时间】:2018-02-16 14:18:06 【问题描述】:

我正在使用

TO_CHAR(TO_DATE(tdj_tran_dt,'DD-MON-RRRR'),'DD-MON-RRRR')    

在我的一个观点中。

基础数据的形式为DD-MON-YY,我必须在屏幕上以DD-MON-YYYY 的形式显示它。

最初我单独使用to_char(tdj_Tran_dt,'DD-MON-YYYY'),但没有成功。例如,20-OCT-17 将变为 20-OCT-0017。我的系统已迁移数据,因此在插入表时更改数据的形式将无济于事。所以为此我使用了TO_CHAR(TO_DATE(tdj_tran_dt,'DD-MON-RRRR'),'DD-MON-RRRR'),它似乎在除unix之外的任何地方都可以使用。 我有一个 proc 文件(通过 linux 运行),它调用这个视图并以 xls 格式写入数据。但在 proc 中打开游标时会出现 Oracle 错误 ORA-01843。将其改回to_char(tdj_Tran_dt,'DD-MON-YYYY') 似乎可以工作,但会带回原来的问题。

我只想知道数据库中是否有一些设置可以更改以解决此问题。我在两个不同的环境中运行相同的东西,并且 not a valid month 错误似乎只发生在一个环境中。 我检查了 nls_parameters ,这在两种环境中似乎都是相同的。

NLS_LANGUAGE    AMERICAN
NLS_TERRITORY   AMERICA
NLS_CURRENCY    $
NLS_ISO_CURRENCY    AMERICA
NLS_NUMERIC_CHARACTERS  .,
NLS_CALENDAR    GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE   AMERICAN
NLS_CHARACTERSET    AL32UTF8
NLS_SORT    BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT    DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT  HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY   $
NLS_NCHAR_CHARACTERSET  AL16UTF16
NLS_COMP    BINARY
NLS_LENGTH_SEMANTICS    BYTE
NLS_NCHAR_CONV_EXCP FALSE

我检查了很多地方,但没有解决方案。如果有人知道如何解决这个问题,请帮忙。

【问题讨论】:

为什么要将日期存储在varchar 列中? 如果“基础数据的格式为 DD-MON-YY”,那么为什么要使用 DD-MON-RRRR 而不是 DD-MON-RR ^ 即尝试做TO_CHAR(TO_DATE(tdj_tran_dt,'DD-MON-RR'),'DD-MON-YYYY') 底层 tdj_tran_dt 列是字符串 (varchar2),还是 Oracle date 有一些错误输入的世纪? TO_CHAR(TO_DATE(tdj_tran_dt,'DD-MON-RRRR'),'DD-MON-RRRR') 。这段代码毫无意义,基本上是无操作的。 【参考方案1】:

我将大胆猜测tdj_tran_dt 实际上是一个DATE 列,因为您提到您使用的是to_char(tdj_tran_dt,'DD-MON-YYYY'),如果它是一个字符串,它将失败。 (如果nls_date_format'DD-MON-RRRR' 不兼容,这也可以解释为什么to_date(tdj_tran_dt,'DD-MON-RRRR') 在另一个环境中失败。)因此问题是某些日期被错误地输入为0017 年等,即公元1 世纪.

如果是这种情况,那么您可能希望通过丢弃世纪并替换更接近的世纪来清理大量过期的日期,同时保留更接近今天的日期。

with demo (tdj_tran_dt) as
     ( select date '0017-01-30' from dual union all
       select date '1917-01-30' from dual union all
       select date '1960-01-30' from dual union all
       select date '2017-01-30' from dual )
select tdj_tran_dt
     , to_date(to_char(tdj_tran_dt,'DD-MON-YY'),'DD-MON-RR') as fixed_tran_dt
from   demo
order by tdj_tran_dt;

TDJ_TRAN_DT  FIXED_TRAN_DT
------------ -------------
30-JAN-0017  30-JAN-2017
30-JAN-1917  30-JAN-2017
30-JAN-1960  30-JAN-1960
30-JAN-2017  30-JAN-2017

【讨论】:

以上是关于不是有效的月份 - SQL ORA-01843 - 在 unix 中的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01843 - 不是有效的月份 oracle SQL

不是有效的月份 - SQL ORA-01843 - 在 unix 中

“ORA-01843: 不是一个有效的月份”错误

ORA-01843 不是有效月份 - 比较日期

ORA-01843: 不是一个有效的月份

ORA-01843: 不是有效的月份 JPA