2015-05-29 45 views
0

我有2個用包含時間戳的毫秒的XMLType列和一些測試數據僅在分離器不同的(。)的表的Oracle 11g數據庫:錯誤在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>')); 

當我嘗試使用以下語句提取時間戳時,它無法使用一個數據庫中的第一個文檔或另一個數據庫上的第二個文檔。

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; 

的錯誤,我得到:

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:版本= 11.2.0.1.0,NLS_CHARACTERSET = AL32UTF8 - >在文檔2上失敗
  • DB2:version = 11.2.0.2.0,NLS_CHARACTERSET = WE8MSWIN1252 - >在文檔1上失敗

DB1具有我期望的行爲。有人知道爲什麼這些數據庫的行爲不同以及如何解決DB2中的問題?

由於提前, 奧利弗

回答

1

我的猜測是,NLS_TIMESTAMP_FORMAT是兩個數據庫之間的不同。

然而,而不是強制的隱式轉換在XMLTABLE水平下降,我會做在選擇列表中顯式轉換:

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設置。

+0

時間戳和日期格式NLS_TIME_FORMAT,NLS_TIMESTAMP_FORMAT,NLS_TIME_TZ_FORMAT,NLS_TIMESTAMP_TZ_FORMAT在兩個數據庫上都相同。 – Pakkanen

+0

我曾希望使用隱式轉換,因爲這些XML文檔來自外部源,並且時間戳格式可能不同,因此顯式轉換對我無法可靠工作。 我想,最後我將這個轉換回到應用層,並使用Java和JodaTime。 – Pakkanen