Oracle 将数据插入时间戳数据类型列将返回ORA-01858:在预期为数字的位置找到非数字字符

Oracle 将数据插入时间戳数据类型列将返回ORA-01858:在预期为数字的位置找到非数字字符,oracle,Oracle,我们的应用程序正在尝试以“Tue Feb 26 15:30:00 EST 2016”格式将数据插入到时间戳(6)数据类型的列(FLD_时间戳)中。我们收到“ORA-01843:非有效月份” 编写触发器将输入数据转换为时间戳格式,如下所示: SQL> create or replace trigger test_wifi before insert on ISG_SESSION_tempfeb15 for each row 2 begin 3 :NEW.f

我们的应用程序正在尝试以“Tue Feb 26 15:30:00 EST 2016”格式将数据插入到时间戳(6)数据类型的列(FLD_时间戳)中。我们收到“ORA-01843:非有效月份”

编写触发器将输入数据转换为时间戳格式,如下所示:

    SQL> create or replace trigger test_wifi before insert on ISG_SESSION_tempfeb15 for each row
      2  begin
      3  :NEW.fld_timestamp :=to_char(to_timestamp_tz(':NEW.fld_timestamp','Dy Mon DD hh24:mi:ss TZD YYYY'),'DD-MON-YY hh:mi:ss AM');
      4  end;
      5  /
触发器已创建

当我尝试插入数据时,它仍然出错:

    SQL> insert into         ISG_SESSION_tempfeb15(isg_session_id,mac_address,nas_ip,fld_timestamp,created_dte)
      2  values('5','6','7','Wed Jan 13 16:29:00 EST 2016','16-FEB-16 03:05:00.0000');
    values('5','6','7','Wed Jan 13 16:29:00 EST 2016','16-FEB-16 03:05:00.0000')
                       *
    ERROR at line 2:
    ORA-01858: a non-numeric character was found where a numeric was expected

有人能告诉我怎么解决这个问题吗?提前感谢。

为什么在转换为时间戳后必须添加字符?

为什么在转换为时间戳后必须添加字符?

这是因为不能将数据转换作为触发器的一部分。问题是insert语句希望以正确的格式传递数据

您需要做的是取消触发器并将insert语句修改为类似以下内容:

insert into ISG_SESSION_tempfeb15 (isg_session_id,
                                   mac_address,
                                   nas_ip,
                                   fld_timestamp,
                                   created_dte)
values ('5',
        '6',
        '7',
        to_timestamp_tz('Wed Jan 13 16:29:00 EST 2016', 'Dy Mon dd hh24:mi:ss TZR yyyy'),
        to_timestamp('16-FEB-2016 03:05:00.0000', 'dd-MON/yyyy hh24:mi:ss.ff4'));
注意,我已经修改了你要传递的创建年份,改为四位数,而不是两位数。Y2K不是童话

另外,请注意,如果列的数据类型为TIMESTAMP(6),而不是带有时区的TIMESTAMP(6),则将丢失有关数据时区的任何信息

例如


查看第一列看起来如何包含相同的值,但第二列显示不包含相同的值?

这是因为不能将数据转换作为触发器的一部分。问题是insert语句希望以正确的格式传递数据

您需要做的是取消触发器并将insert语句修改为类似以下内容:

insert into ISG_SESSION_tempfeb15 (isg_session_id,
                                   mac_address,
                                   nas_ip,
                                   fld_timestamp,
                                   created_dte)
values ('5',
        '6',
        '7',
        to_timestamp_tz('Wed Jan 13 16:29:00 EST 2016', 'Dy Mon dd hh24:mi:ss TZR yyyy'),
        to_timestamp('16-FEB-2016 03:05:00.0000', 'dd-MON/yyyy hh24:mi:ss.ff4'));
注意,我已经修改了你要传递的创建年份,改为四位数,而不是两位数。Y2K不是童话

另外,请注意,如果列的数据类型为TIMESTAMP(6),而不是带有时区的TIMESTAMP(6),则将丢失有关数据时区的任何信息

例如


查看第一列看起来如何包含相同的值,但第二列显示不包含相同的值?

尝试更改:NEW.fld\u timestamp'为:NEW.fld\u timestamp

:NEW.fld_timestamp :=to_char(to_timestamp_tz(:NEW.fld_timestamp,'Dy Mon DD hh24:mi:ss TZD YYYY'),'DD-MON-YY hh:mi:ss AM');

这是您的问题

尝试将:NEW.fld\u timestamp“更改为:NEW.fld\u timestamp

:NEW.fld_timestamp :=to_char(to_timestamp_tz(:NEW.fld_timestamp,'Dy Mon DD hh24:mi:ss TZD YYYY'),'DD-MON-YY hh:mi:ss AM');

这是您的问题

您确定所有第一个字段都是varchar吗?我认为至少有一个字段(最有可能是isg_session_id)是一个数字,并且您正在插入字符串“5”。您确定所有这些字段都是varchar吗?我认为前三个字段中至少有一个(最有可能是isg_session_id)是一个数字,而您正在插入“5”,这是一个字符串。我感觉他的问题在于前三个字段中的一个,该字段期望数字并得到一个varchar。根据错误消息中星号的位置判断,我怀疑是传递到timestamp列的值导致了问题。该字符串的格式肯定不是标准格式!但是,对于其他列的数据类型,您提出了一个非常好的观点@Boneist—问题是,我们无法控制将数据插入oracle表的应用程序,因此我们需要在db端自己做一些事情,并考虑使用触发器进行此操作。然后,我建议您使用两列来保存数据。1具有传入的字符串,另一个具有正确的时间戳转换。然后可以使用触发器根据字符串列填充新列。类似于
new.field\u timestamp\u ts:=to\u timestamp\u tz(new.field\u timestamp\u str,'Dy Mon dd hh24:mi:ss TZR yyyy')。或者,您可以使用一个执行转换的虚拟列来代替触发器(触发器将批量数据加载转换为逐行处理)。您需要决定是在加载时承受性能损失,还是reading@Boneist-你是说我们不能在通过触发器插入时操纵数据吗?我感觉他的问题在于前3个字段之一,期望数字并得到一个VARCHAR,根据错误消息中星号的位置判断,我怀疑是传递到timestamp列的值导致了问题。该字符串的格式肯定不是标准格式!但是,对于其他列的数据类型,您提出了一个非常好的观点@Boneist—问题是,我们无法控制将数据插入oracle表的应用程序,因此我们需要在db端自己做一些事情,并考虑使用触发器进行此操作。然后,我建议您使用两列来保存数据。1具有传入的字符串,另一个具有正确的时间戳转换。然后可以使用触发器根据字符串列填充新列。类似于
new.field\u timestamp\u ts:=to\u timestamp\u tz(new.field\u timestamp\u str,'Dy Mon dd hh24:mi:ss TZR yyyy')。或者,您可以使用一个执行转换的虚拟列来代替触发器(触发器将批量数据加载转换为逐行处理)。您需要决定是在加载时承受性能损失,还是reading@Boneist-您是说我们不能在通过触发器插入时操作数据吗?SQL>在ISG会话上插入之前创建或替换触发器测试\u wifi \u tempfeb15,每行2开始3:NEW.fld\u timestamp:=to\u timestamp\u tz(':NEW.fld_timestamp','Dy-Mon-DD-hh24:mi:ss-TZD-YYYY');4-end;5/Trigger-created@sagi-即使在创建了不带to_字符的触发器之后,它仍然返回相同的错误。值('5','6','7','Wed Jan 13 16:29:00 EST 2016','16-FEB-16 03:05:00.0000'))*第2行错误:ORA-01858:在需要数字的位置发现非数字字符SQL>create or replace trigger test\u wifi before insert on ISG\u SESSION\u tempfeb15为每行2开始3:NEW.fld\u timestamp:=to\u timestamp\u tz(':NEW.fld\u tim)