【问题标题】:"Not a valid month" on an INSERT statementINSERT 语句中的“不是有效月份”
【发布时间】:2023-04-03 03:40:02
【问题描述】:

我有一条sql语句:

Insert into MYSCHEMA.TABLE1 (ID,MY_DATE) values (167600,to_timestamp('15-APR-14 01.36.58.803000000 PM','DD-MON-RR HH.MI.SS.FF AM'));

当我读到这种格式是正确的(如here 所述)但oracle 返回错误SQL Error: ORA-01843: not a valid month。知道如何解决这个问题吗?我使用的是 Oracle Database 11b 快捷版。

【问题讨论】:

  • my_date 是日期还是时间戳字段?如果是约会,您的NLS_DATE_FORMAT 和NLS_TIMESTAMP_FORMAT 设置为什么?听起来像是一个隐式转换问题。或者可能不太可能是NLS_DATE_LANGUAGE 问题。
  • NLS_DATE_LANGUAGE 设置为四月的缩写不是 APR 的语言听起来不错。
  • MikeW,正如我在 oracle 网站上看到的,MON 是一种有效的月份格式。 @AlexPoole,这是一种时间戳格式。 NLS_TIMESTAMP_FORMAT=RR/MM/DD HH24:MI:SSXFF
  • MY_DATE 是一个 TIMESTAMP(3) 并且 NLS_DATE_FORMAT=RR/MM/DD。顺便说一句,这有关系吗?我以为to_timestamp函数的第二个参数是时间戳格式。
  • 只有在进行隐式转换时才重要;如果my_date 是时间戳(尽管名称令人困惑),则不存在,并且如果 NLS 格式仍然匹配。这样NLS_DATE_LANGUAGE 就错了;还是在设置日期/时间戳字段的表上有触发器?

标签: sql database oracle oracle11g


【解决方案1】:

除非您在设置日期或时间戳列的表上有一个触发器,这会在完整的错误堆栈中给出一些指示,否则您的 NLS_DATE_LANGUAGE 听起来并不需要英语月份的缩写。

你所拥有的是英文有效的:

alter session set nls_timestamp_format = 'RR/MM/DD HH24:MI:SSXFF';
alter session set nls_date_language ='ENGLISH';

select to_timestamp('15-APR-14 01.36.58.803000000 PM',
  'DD-MON-RR HH.MI.SS.FF AM') as my_date
from dual;

MY_DATE                   
---------------------------
14/04/15 13:36:58.803000000 

但如果您会话的默认日期语言是波兰语(根据您的个人资料猜测),则会出现此错误 - 错误消息仍为英语:

alter session set nls_date_language ='POLISH';

select to_timestamp('15-APR-14 01.36.58.803000000 PM',
  'DD-MON-RR HH.MI.SS.FF AM') as my_date
from dual;

SQL Error: ORA-01843: not a valid month
01843. 00000 -  "not a valid month"

如果您不想将会话设置为英语,您可以通过提供 optional third parameter to to_timestamp() 来覆盖特定语句:

alter session set nls_date_language ='POLISH';

select to_timestamp('15-APR-14 01.36.58.803000000 PM',
  'DD-MON-RR HH.MI.SS.FF AM',
  'NLS_DATE_LANGUAGE=ENGLISH') as my_date
from dual;

MY_DATE                   
---------------------------
14/04/15 13:36:58.803000000 

您还可以通过使用月份编号而不是月份名称或使用 ANSI timestamp literal syntax 来完全避免此问题:

select timestamp '2014-04-15 13:36:58.803' from dual;

TIMESTAMP'2014-04-1513:36:58.803'
---------------------------------
14/04/15 13:36:58.803000000       

这些方法也都适用于日期列; the to_date() function 同样受 NLS 设置的影响,并且具有相同的可选日期语言参数。

【讨论】:

  • 谢谢,现在可以使用了。问题是我正在使用 sqldeveloper,它存储有关 NLS 表的信息。我不知道本地应用程序可以存储这些信息。
猜你喜欢
  • 2012-01-10
  • 2018-01-01
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
相关资源
最近更新 更多