在Oracle 11g中从XMLType列选择时间戳时出错

在Oracle 11g中从XMLType列选择时间戳时出错,oracle,oracle11g,timestamp,xmltype,timestamp-with-timezone,Oracle,Oracle11g,Timestamp,Xmltype,Timestamp With Timezone,我有两个Oracle 11g数据库,其中一个表包含一个XMLType列和一些测试数据,这些数据仅在分隔符中有所不同,时间戳的毫秒数为: create table TEST_TIMESTAMP ( ID number(19,0) constraint "NN_TEST_TIMESTAMP_ID" not null, DOC xmltype constraint "NN_TEST_TIMESTAMP_DOC" not null ); insert into TEST_TIMES

我有两个Oracle 11g数据库,其中一个表包含一个XMLType列和一些测试数据,这些数据仅在分隔符中有所不同,时间戳的毫秒数为:

create table TEST_TIMESTAMP (
  ID  number(19,0) constraint "NN_TEST_TIMESTAMP_ID" not null,
  DOC xmltype      constraint "NN_TEST_TIMESTAMP_DOC" not null
);

insert into TEST_TIMESTAMP values ( 1, xmltype('<?xml version="1.0" encoding="utf-8"?><test><ts>2015-04-08T04:55:33.11</ts></test>'));
insert into TEST_TIMESTAMP values ( 2, xmltype('<?xml version="1.0" encoding="utf-8"?><test><ts>2015-04-08T04:55:33,11</ts></test>'));
我得到的错误是:

ORA-01858: a non-numeric character was found where a numeric was expected
01858. 00000 - "a non-numeric character was found where a numeric was expected"
*Cause: The input data to be converted using a date format model was
        incorrect.  The input data did not contain a number where a number was
        required by the format model.
*Action:   Fix the input data or the date format model to make sure the
           elements match in number and type.  Then retry the operation.
我发现这些数据库之间的唯一区别是:

DB1:version=11.2.0.1.0,NLS_CHARACTERSET=AL32UTF8->在文档2上失败 DB2:version=11.2.0.2.0,NLS_CHARACTERSET=WE8MSWIN1252->在文档1上失败 DB1具有我所期望的行为。有人知道为什么这些数据库的行为不同,以及如何在DB2中解决这个问题吗

提前感谢,,
Oliver

我猜两个数据库的nls\u时间戳格式不同

但是,我不会在XMLTABLE级别强制进行隐式转换,而是在select列表中进行显式转换:

with test_timestamp as (select 1 id, xmltype('<?xml version="1.0" encoding="utf-8"?><test><ts>2015-04-08T04:55:33.11</ts></test>') doc from dual union all
                        select 2 id, xmltype('<?xml version="1.0" encoding="utf-8"?><test><ts>2015-04-08T04:55:33,11</ts></test>') doc from dual)
select x.original,
       to_timestamp(x.original, 'yyyy-mm-dd"T"hh24:mi:ss,ff2') result
from   test_timestamp t,
       xmltable('/test' passing t.doc
                columns original varchar2(50) path 'ts') x;

ORIGINAL                                           RESULT                                            
-------------------------------------------------- --------------------------------------------------
2015-04-08T04:55:33.11                             08/04/2015 04:55:33.110000000
2015-04-08T04:55:33,11                             08/04/2015 04:55:33.110000000

注意,我发现使用ss.ff2是错误的,但ss.ff2处理这两种情况都很好。不过,我不确定这是否依赖于其他nls设置。

时间戳和日期格式nls\U TIME\U格式,nls\U Timestamp\U格式,nls\U TIME\U TZ\U格式,NLS_TIMESTAMP_TZ_格式在两个数据库上都是相同的。我希望使用隐式转换,因为这些XML文档来自外部源,并且时间戳格式可能不同,因此显式转换对我来说不可靠。我想,最后我将把这个转换移回应用层,并使用Java和JodaTime。
with test_timestamp as (select 1 id, xmltype('<?xml version="1.0" encoding="utf-8"?><test><ts>2015-04-08T04:55:33.11</ts></test>') doc from dual union all
                        select 2 id, xmltype('<?xml version="1.0" encoding="utf-8"?><test><ts>2015-04-08T04:55:33,11</ts></test>') doc from dual)
select x.original,
       to_timestamp(x.original, 'yyyy-mm-dd"T"hh24:mi:ss,ff2') result
from   test_timestamp t,
       xmltable('/test' passing t.doc
                columns original varchar2(50) path 'ts') x;

ORIGINAL                                           RESULT                                            
-------------------------------------------------- --------------------------------------------------
2015-04-08T04:55:33.11                             08/04/2015 04:55:33.110000000
2015-04-08T04:55:33,11                             08/04/2015 04:55:33.110000000