Oracle 插入时间戳 - AM/A.M.或下午/下午必需的

Posted

技术标签:

【中文标题】Oracle 插入时间戳 - AM/A.M.或下午/下午必需的【英文标题】:Oracle insert timestamp - AM/A.M. or PM/P.M. required 【发布时间】:2013-12-20 09:48:06 【问题描述】:

在 SQL Developer 中,我创建了一个导出的 .sql 文件(一个非常大的文件)。它包含数百个插入,例如:

"Insert into SCHEMA.TABLE (
 ... ,
 CREATEDATE,
 MODIFIEDDATE,
 ....
) 
values (
 ... , 
 to_timestamp('20-AUG-12 01.09.53.271000000 AM','DD-MON-RR HH.MI.SS.FF AM'),
 to_timestamp('20-AUG-12 01.09.53.271000000 PM','DD-MON-RR HH.MI.SS.FF PM'),
 ...
);"

当我在 SQL Developer 中运行它时,它运行良好。但是我无法使用 SQL Developer 导入一点 .sql 文件(或者我不知道该怎么做)。

当我使用 SQL*Plus 运行它时,出现以下错误:

ORA-01855:上午/上午或下午/下午必填

当我从插入中删除 AM/PM 关键字时,SQL*Plus 可以插入行,但没有运气。上午/下午有什么问题?

这是确切的插入命令:

Insert into SCHEMA.TABLE(

ENTRYID,GROUPID,COMPANYID,USERID,USERNAME,CREATEDATE,MODIFIEDDATE,
CLASSNAMEID,CLASSPK,CLASSUUID,VISIBLE,STARTDATE,ENDDATE,PUBLISHDATE,
EXPIRATIONDATE,MIMETYPE,TITLE,DESCRIPTION,SUMMARY,URL,HEIGHT,WIDTH,
PRIORITY,VIEWCOUNT

) values (

11902,11005,10136,10178,'Test Test',
to_timestamp('20-AUG-12 01.09.53.271000000 AM','DD-MON-RR HH.MI.SS.FF AM'),
to_timestamp('20-AUG-12 01.09.53.271000000 PM','DD-MON-RR HH.MI.SS.FF PM'),
10076,11900,'AAA',1,null,null,null,null,null,
'ABC','XyZ',null,null,0,0,0,2563

);

【问题讨论】:

上午/下午应该没有问题;将to_timestamp() 调用插入到具有timestamp 列的表中可以在SQLPlus 中正常工作。据我所知,AM/PM 文字值不受 NLS 设置的影响,所以我认为这不是问题。我必须假设您已经发布了*确切您正在运行的内容;不过,没有更改名称的完整命令以及有效的修改版本会让人更有信心。 SQL Developer 有什么问题;你可以打开一个脚本文件然后'运行脚本'? 你能从 SQL 文件中发布一个数据样本吗?是总是使用'DD-MON-RR HH.MI.SS.FF AM' 格式还是总是/有时使用'DD-MON-RR HH24.MI.SS.FF' 呵呵,原来经络指标是NLS敏感的。 select value from nls_session_parameters where parameter = 'NLS_DATE_LANGUAGE' 在 SQL*Plus 中为您提供了什么?希望不是英语;斯洛伐克语将是一个很好的答案...... 【参考方案1】:

我能看到的唯一直接重现此问题的方法是更改​​ NLS 设置;但不是NLS_LANGUAGE,因为这也会影响错误消息。正如你所料,使用英语是可以的:

SQL> alter session set NLS_DATE_LANGUAGE='ENGLISH';

Session altered.

SQL> select value from nls_session_parameters
  2  where parameter = 'NLS_DATE_LANGUAGE';

VALUE
--------------------------------------------------------------------------------
ENGLISH

SQL> insert into t42 (createddate)
  2  values (to_timestamp('20-08-12 01.09.53.271000000 AM','DD-MM-RR HH.MI.SS.FF PM'));

1 row created.

仅更改 NLS_DATE_LANGUAGE 会重现您的错误:

alter session set NLS_DATE_LANGUAGE='SLOVAK';

Session altered.

SQL> insert into t42 (createddate)
  2  values (to_timestamp('20-AUG-12 01.09.53.271000000 AM','DD-MON-RR HH.MI.SS.FF PM'));
values (to_timestamp('20-AUG-12 01.09.53.271000000 AM','DD-MON-RR HH.MI.SS.FF PM'))
                     *
ERROR at line 2:
ORA-01855: AM/A.M. or PM/P.M. required

更改NLS_LANGUAGE,直接或通过影响它的东西,也会使错误消息看起来不同:

SQL> alter session set NLS_LANGUAGE = 'SLOVAK';

Relácia zmenená.

SQL> insert into t42 (createddate)
  2  values (to_timestamp('20-AUG-12 01.09.53.271000000 AM','DD-MON-RR HH.MI.SS.FF PM'));
values (to_timestamp('20-AUG-12 01.09.53.271000000 AM','DD-MON-RR HH.MI.SS.FF PM'))
                     *
ERROR v riadku 2:
ORA-01855: vy¿aduje sa AM/A.M. alebo PM/P.M.

您需要一种仍将AUG 识别为有效月份但不使用AM/PM 的语言;斯洛伐克语似乎符合要求,所以我猜这可能就是你来自的地方。其他语言也可以这样做。有点奇怪,NLS_LANGUAGE 仍然设置时的错误消息显示 AM/PM,但to_char(sysdate, 'HH AM') 表示消息错误。仅设置NLS_DATE_LANGUAGE 时,消息仍为英文(例如,尝试使用土耳其语,但您必须更改月份名称或切换使用月份编号),并且始终显示 AM/PM。

如果发生这种情况,请在运行此脚本之前将 NLS_DATE_LANGUAGE 更改为英文;或在执行导出之前更改您的 SQL Developer 设置以使用斯洛伐克语(或您实际使用的任何内容) - 这有望使导出使用 DOPOLUDNIE/POPOLUDNIE,但如果不这样做,我不会完全感到惊讶;或更改 SQL Developer NLS_TIMESTAMP_FORMAT 以使用 24 小时制(以及 4 位数的年份和月份数字而不是名称)进行导出,这将完全避免该问题。当然,也可以从 SQL Developer 运行脚本。

【讨论】:

谢谢大家!!!添加此“更改会话集 NLS_DATE_LANGUAGE='ENGLISH';”帮帮我...非常感谢您【参考方案2】:

Alex 的回答很好地描述了这个问题;但是,如果您能够稍微更改生成的插入语句,则有一个更简单的解决方案。 TO_TIMESTAMP() 有第三个参数,它允许您在插入本身中指定 NLS_DATE_LANGUAGE。

create table a ( tstamp timestamp );

Table created.

insert into a
values (to_timestamp( '20-08-12 01.09.53.271000000 AM'
                    , 'DD-MM-RR HH.MI.SS.FF PM'
                    , 'nls_date_language = ENGLISH'));

1 row created.

select *
  from a;

TSTAMP
------------------------------------------------------
20-AUG-12 01.09.53.271000

然后,您无需更改会话的日期语言,或在之后将其更改回来。

【讨论】:

如果它们来自 SQL Developer 的“导出”,那么通过并修改它们会有点痛苦,但是是的,不错的选择。 我不知道@Alex...我希望 Oracle 的工具可以让你使用 Oracle,但我过去一直错了 :-)。【参考方案3】:

没有任何数据可查看,我无法确定,但听起来您的“大 SQL 文件”并不总是(或有时)具有您期望的格式的时间戳,并且未使用 AMPM.

尝试使用 24 小时制而不是 AMPM,看看是否与“大 SQL 文件”中的数据匹配:

 ...
 to_timestamp('20-AUG-12 01.09.53.271000000','DD-MON-RR HH24.MI.SS.FF'),
 to_timestamp('20-AUG-12 13.09.53.271000000','DD-MON-RR HH24.MI.SS.FF'),
 ...

【讨论】:

以上是关于Oracle 插入时间戳 - AM/A.M.或下午/下午必需的的主要内容,如果未能解决你的问题,请参考以下文章

将 UTC 时间戳(毫秒)插入 Oracle 时间戳列

使用 Coldfusion 设置 Oracle 时间戳

在 Oracle 中减去日期

怎样手动插入时间 oracle

java 将当前时间戳插入具有时间戳类型的Oracle数据库列

在oracle 10g sql plus中将日期和时间插入时间戳