Encountering SQL Error: ORA-01843: not a valid month

Encountering SQL Error: ORA-01843: not a valid month

我使用此查询
创建了一个 table CREATE TABLE Store (id number(11) primary key not null, opening_time timestamp CHECK (EXTRACT(HOUR FROM opening_time) > 8 || NULL));

现在,当我尝试使用 insert into Store values(1, '04/04/2012 13:35 PM'); 插入一些数据时,我遇到了这个错误 SQL Error: ORA-01843: not a valid month

我做错了什么?

您不必在 table 中插入主键值。它是自动生成的。并尝试使用 TO_DATE 函数提供您的日期格式,例如:

insert into Store values(to_date('04/04/2012 13:35 PM','DD/MM/YYYY HH:MI AM'));

SQL Error: ORA-01843: not a valid month

'04/04/2012 13:35 PM' 字符串 而不是 日期 。您应该始终使用 TO_DATE 将字符串显式转换为日期。永远不要依赖隐式数据类型转换。您可能只是幸运地依赖于您的 特定于区域设置的 NLS 设置 。但是,如果 NLS 设置不同,它将不起作用。因此,始终使用 TO_DATE 使用适当的 格式掩码 .

将文字转换为日期

查看日期时间值,不需要使用timestamp,只需使用DATE数据类型即可。它可以保持到秒的精度。

CREATE TABLE Store (id number(11) primary key not null, 
                    opening_time timestamp 
                    CHECK (EXTRACT(HOUR FROM opening_time) > 8 || NULL)); 

insert into Store 
values(1, TO_DATE('04/04/2012 13:35 PM', 'DD/MM/YYYY HH:MI', 'nls_date_language=ENGLISH'));

您也可以使用 ANSI date/timestamp literal,它使用 固定格式 ,因此它是 NLS独立.

DATE '2012-04-04' 

TIMESTAMP '2012-04-04 13:35:00'

insert into Store values(1, '04-APR-2012 13:35 PM');

这对我有用。

好的做法是将 to_date 函数与您的数据格式一起使用。 在你的情况下它将:

insert into Store 
values(1, to_date('04/04/2012 13:35', 'DD/MM/YYYY HH24:mi'));

您可以在 official documentation 中找到有关此功能的更多详细信息。

'04/04/2012 13:35 PM' 不是日期 - 它是字符串。

当使用 NLS_DATE_FORMAT 会话参数的值作为格式掩码(注意:这是一个会话参数,属于客户端;它不是全局设置)。如果非日期文字匹配此格式,那么它会工作(如果不匹配,则不会) - 但是,如果 NLS_DATE_FORMAT 被更改,那么它会立即中断(任何一个都是巨大的痛苦进行调试,因为正在运行的代码不会,但没有人会更改代码。

您可以通过以下查询找到您目前的 NLS_DATE_FORMAT

SELECT VALUE
FROM   NLS_SESSION_PARAMETERS
WHERE  PARAMETER = 'NLS_DATE_FORMAT';

最好明确使用带有正确格式掩码的 TO_DATE() 或使用 ANSI/ISO 日期文字(即 DATE '2012-04-04'TIMESTAMP '2012-04-04 13:35')。

你可以这样做:

INSERT INTO STORE ( id, opening_time )
  VALUES( 1, TO_DATE( '04/04/2012 13:35', 'DD/MM/YYYY HH24:MI' );

(您不需要 AM/PM,因为小时部分已经采用 24 小时制)

INSERT INTO STORE ( id, opening_time )
  VALUES( 1, TIMESTAMP '2012-04-04 13:35:00' );

(使用 Oracle 将隐式转换为日期的 ANSI/ISO 时间戳文字)