简体   繁体   中英

Error when selecting timestamp from XMLType column in Oracle 11g

I have 2 Oracle 11g databases with a table containing a XMLType column and some test data differing only in the separator (.,) for the milliseconds of the timestamp:

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>'));

When I try to extract the timestamp with the following statements, it fails either with the first document on one database or with the second document on the other database.

select x.*
from TEST_TIMESTAMP t,
     xmltable( 
     '/test'
     passing t.DOC
     columns
       ORIGINAL varchar2(50) path 'ts',
       RESULT timestamp with time zone path 'ts'
 ) x
 where t.ID = 1;

 select x.*
 from TEST_TIMESTAMP t,
 xmltable( 
      '/test'
      passing t.DOC
      columns
        ORIGINAL varchar2(50) path 'ts',
        RESULT timestamp with time zone path 'ts'
 ) x
 where t.ID = 2;

The error I get:

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.

The only differences between those databases I've found are:

  • DB1: version=11.2.0.1.0, NLS_CHARACTERSET=AL32UTF8 -> fails on document 2
  • DB2: version=11.2.0.2.0, NLS_CHARACTERSET=WE8MSWIN1252 -> fails on document 1

DB1 has the behaviour that I would expect. Does anybody know why those databases behave differently and how to fix the issue in DB2?

Thanks in advance, Oliver

My guess is that the nls_timestamp_format is different between the two databases.

However, rather than forcing the implicit conversion down at the XMLTABLE level, I would do an explicit conversion in the select list:

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

NB I found that using "ss.ff2" errored, but "ss,ff2" handled both cases just fine. I'm not sure if that's reliant on some other nls setting or not, though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM