Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Oracle中将XML转换为行和列_Xml_Oracle_Xmltable - Fatal编程技术网

在Oracle中将XML转换为行和列

在Oracle中将XML转换为行和列,xml,oracle,xmltable,Xml,Oracle,Xmltable,在Oracle中将XML转换为行和列: C12和c13有多个值,这就是此查询失败的原因 直到m42,c12和c13在m1、m2、m3等下的值很少 我想在Oracle行和列中获取所有这些值 12:53:06 SYS@r17dev11> select xt.* from T24.FBNK_AA_ACCOUNT_DETAILS x , 13:08:58 2 XMLTABLE('/row' PASSING x.XMLRECORD 13:08:58 3 COLUMNS

在Oracle中将XML转换为行和列:

C12和c13有多个值,这就是此查询失败的原因 直到m42,c12和c13在m1、m2、m3等下的值很少 我想在Oracle行和列中获取所有这些值

        12:53:06 SYS@r17dev11> select xt.* from T24.FBNK_AA_ACCOUNT_DETAILS x ,
13:08:58   2  XMLTABLE('/row' PASSING x.XMLRECORD 
13:08:58   3  COLUMNS
13:08:58   4  "CONTRACT.DATE" DATE  PATH 'c1',
13:08:58   5  "VALUE.DATE" DATE  PATH 'c2',
13:08:58   6  "PAYMENT.START.DATE" DATE PATH 'c5',
13:08:58   7  "MATURITY.DATE" DATE PATH 'c6',
13:08:58   8  "BILL.PAY.DATE"DATE PATH 'c12',
13:08:58   9  "BILL.ID" VARCHAR2(20) PATH 'c13'
13:08:58  10  ) xt where rownum<5;
XMLTABLE('/row' PASSING x.XMLRECORD
*
ERROR at line 2:
ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence    

Elapsed: 00:00:00.03
下面是xml代码 c12和c13包含多个值,我需要表中的所有这些值

 1* select x.XMLRECORD.getClobVal() from T24.FBNK_AA_ACCOUNT_DETAILS x where rownum<2
16:17:31 SYS@r17dev11> /

X.XMLRECORD.GETCLOBVAL()
--------------------------------------------------------------------------------
<row id='AA132364NK43'><c1>20130824</c1><c2>20130824</c2><c3>20130828</c3><c5>20
130927</c5><c6>20380831</c6><c7>CUR</c7><c8>20180827</c8><c11>20130828</c11><c12
>20130927</c12><c12 m='2'>20131027</c12><c12 m='3'>20131127</c12><c12 m='4'>2013
1227</c12><c12 m='5'>20140127</c12><c12 m='6'>20140227</c12><c12 m='7'>20140327<
/c12><c12 m='8'>20140427</c12><c12 m='9'>20140527</c12><c12 m='10'>20140627</c12
><c12 m='11'>20140727</c12><c12 m='12'>20140827</c12><c12 m='13'>20140927</c12><
c12 m='14'>20141027</c12><c12 m='15'>20141127</c12><c12 m='16'>20141227</c12><c1
2 m='17'>20150127</c12><c12 m='18'>20150227</c12><c12 m='19'>20150327</c12><c12
m='20'>20150427</c12><c12 m='21'>20150527</c12><c12 m='22'>20150627</c12><c12 m=
'23'>20150727</c12><c12 m='24'>20150827</c12><c12 m='25'>20150927</c12><c12 m='2
6'>20151027</c12><c12 m='27'>20151127</c12><c12 m='28'>20151227</c12><c12 m='29'
>20160127</c12><c12 m='30'>20160227</c12><c12 m='31'>20160327</c12><c12 m='32'>2
0160427</c12><c12 m='33'>20160527</c12><c12 m='34'>20160627</c12><c12 m='35'>201
60727</c12><c12 m='36'>20160827</c12><c12 m='37'>20160927</c12><c12 m='38'>20161
027</c12><c12 m='39'>20161127</c12><c12 m='40'>20161227</c12><c12 m='41'>2017012
7</c12><c12 m='42'>20170227</c12><c13>AABILL13265WLWSR</c13><c13 m='2'>AABILL132
95PD9RK</c13><c13 m='3'>AABILL133263FXPS</c13><c13 m='4'>AABILL133568M6DK</c13><
c13 m='5'>AABILL14022VH2JB</c13><c13 m='6'>AABILL14053G95RF</c13><c13 m='7'>AABI
LL140814YYC3</c13><c13 m='8'>AABILL14112M0MZ4</c13><c13 m='9'>AABILL14142RRH3P</
c13><c13 m='10'>AABILL14173D6GZJ</c13><c13 m='11'>AABILL14203HY9V6</c13><c13 m='
12'>AABILL142341G2BW</c13><c13 m='13'>AABILL142651P9D9</c13><c13 m='14'>AABILL14
295FC8G1</c13><c13 m='15'>AABILL14326LY4DN</c13><c13 m='16'>AABILL14356GTNDX</c1
3><c13 m='17'>AABILL15022FPV3V</c13><c13 m='18'>AABILL1505397QRV</c13><c13 m='19
'>AABILL15081R8PYH</c13><c13 m='20'>AABILL15112NPQ80</c13><c13 m='21'>AABILL1514
2RS60L</c13><c13 m='22'>AABILL1517394B3C</c13><c13 m='23'>AABILL1520399HHS</c13>
<c13 m='24'>AABILL15234G8QQ6</c13><c13 m='25'>AABILL15265G9TT8</c13><c13 m='26'>
AABILL1529522SSF</c13><c13 m='27'>AABILL15326DJW22</c13><c13 m='28'>AABILL15356B
XFX4</c13><c13 m='29'>AABILL16022LVK4B</c13><c13 m='30'>AABILL160535VKDY</c13><c
13 m='31'>AABILL16082999WH</c13><c13 m='32'>AABILL16113HDW4T</c13><c13 m='33'>AA
BILL16143QBV97</c13><c13 m='34'>AABILL16174QWS79</c13><c13 m='35'>AABILL16204Y60
RR</c13><c13 m='36'>AABILL16235V98PJ</c13><c13 m='37'>AABILL16266XSY2W</c13><c13
 m='38'>AABILL16296GGLQG</c13><c13 m='39'>AABILL16327720SX</c13><c13 m='40'>AABI
LL16357PBM9X</c13><c13 m='41'>AABILL17022R86MS</c13><c13 m='42'>AABILL1705305GMP
</c13><c14>AAACT13265080Q418K</c14><c14 m='2'>AAACT132952XTB10G3</c14><c14 m='3'
我可以一个接一个地得到这样的值

  1     select xt.* from T24.FBNK_AA_ACCOUNT_DETAILS x ,
  2    XMLTABLE('/row' PASSING x.XMLRECORD
  3    COLUMNS
  4    "CONTRACT.DATE" DATE  PATH 'c1',
  5    "VALUE.DATE" DATE  PATH 'c2',
  6    "PAYMENT.START.DATE" DATE PATH 'c5',
  7    "MATURITY.DATE" DATE PATH 'c6',
  8    "BILL.PAY.DATE"  DATE PATH 'c12[@m=8]',
  9    "BILL.ID"   VARCHAR2(512)  PATH 'c13[@m=8]'
 10*  ) xt where rownum<5
16:13:51 SYS@r17dev11> /

CONTRACT. VALUE.DAT PAYMENT.S MATURITY. BILL.PAY.DATE                  BILL.ID
--------- --------- --------- --------- ------------------------------ ----------------------------------------
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-APR-14                      AABILL14112M0MZ4
08-FEB-13 08-FEB-13 13-FEB-13 08-FEB-14
08-FEB-13 08-FEB-13 01-MAR-13 01-AUG-46 01-OCT-13                      AABILL132695KKSX
19-FEB-13 19-FEB-13 01-MAR-13 19-FEB-14 01-OCT-13                      AABILL13269YF6XQ
然后对于其他值,我可以更改m属性,然后我可以得到其他值。但这一解决方案并不实用

  1     select xt.* from T24.FBNK_AA_ACCOUNT_DETAILS x ,
  2    XMLTABLE('/row' PASSING x.XMLRECORD
  3    COLUMNS
  4    "CONTRACT.DATE" DATE  PATH 'c1',
  5    "VALUE.DATE" DATE  PATH 'c2',
  6    "PAYMENT.START.DATE" DATE PATH 'c5',
  7    "MATURITY.DATE" DATE PATH 'c6',
  8    "BILL.PAY.DATE"  DATE PATH 'c12[@m=7]',
  9    "BILL.ID"   VARCHAR2(512)  PATH 'c13[@m=7]'
 10*  ) xt where rownum<5
16:13:23 SYS@r17dev11> /

CONTRACT. VALUE.DAT PAYMENT.S MATURITY. BILL.PAY.DATE                  BILL.ID
--------- --------- --------- --------- ------------------------------ ----------------------------------------
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-MAR-14                      AABILL140814YYC3
08-FEB-13 08-FEB-13 13-FEB-13 08-FEB-14
08-FEB-13 08-FEB-13 01-MAR-13 01-AUG-46 01-SEP-13                      AABILL13239DK15P
19-FEB-13 19-FEB-13 01-MAR-13 19-FEB-14 01-SEP-13                      AABILL132391SQT3
我正在检查更多的文档,我们可以在一行中获得xml格式的所有值。我尝试了下面的代码,但无法完成,因为它会给出各种各样的错误

我找到的文档->

我只想将c13中的所有多个值放在一行中,并且它包含超过20个的多个值

嗨,亚历克斯

我的实际需求是将xml中的所有数据转换成csv格式,每个值都在单独的列中,但c12和c13使其非常困难,因为它们包含多达42个属性,如m1、m2、m42。现在,当我使用查询时,它将我输出到单个列中,但包装会使在excel中很难读取。输出被excel搞得一团糟。是否有可能在不同的列中获得m的每个值,或者使用其他技术来实现这一点。我认为以xml格式获取它会很好。表包含300k行

因此,最好以xml格式或varchar格式获取c12和c13的数据,每个m值在单独的列中。
唯一的条件是,它应该是在excel上可读的格式。我需要你的建议。表包含300k行

您可以在XPath表达式中使用一个循环,将XML转换为每个账单日期/ID对的单独虚拟行,类似于:

select xt.*
from t24.fbnk_aa_account_details x
cross join xmltable('for $r in /row, $i in (1 to count(row/c12))
  return (
    element {"row"} {
      element {"c1"} {$r/c1},
      element {"c2"} {$r/c2},
      element {"c5"} {$r/c5},
      element {"c6"} {$r/c6},
      element {"c12"} {$r/c12[$i]},
      element {"c13"} {$r/c13[$i]}
    }
  )'
  passing x.xmlrecord 
  columns
    "CONTRACT.DATE" date path 'c1',
    "VALUE.DATE" date path 'c2',
    "PAYMENT.START.DATE" date path 'c5',
    "MATURITY.DATE" date path 'c6',
    "BILL.PAY.DATE" date path 'c12',
    "BILL.ID" varchar2(20) path 'c13'
) xt
演示一个合成的相同XML文档,该文档引发与原始查询相同的错误:

-- CTE for sample data
with fbnk_aa_account_details (xmlrecord) as (
  select xmltype('<row>
<c1>2010-01-02</c1>
<c2>2010-02-03</c2>
<c5>2010-03-04</c5>
<c6>2019-12-31</c6>
<c12>2010-04-05</c12>
<c13>m1</c13>
<c12>2010-05-05</c12>
<c13>m2</c13>
<c12>2010-06-05</c12>
<c13>m3</c13>
</row>') from dual
)
-- actual query
select xt.*
from fbnk_aa_account_details x
cross join xmltable('for $r in /row, $i in (1 to count(row/c12))
  return (
    element {"row"} {
      element {"c1"} {$r/c1},
      element {"c2"} {$r/c2},
      element {"c5"} {$r/c5},
      element {"c6"} {$r/c6},
      element {"c12"} {$r/c12[$i]},
      element {"c13"} {$r/c13[$i]}
    }
  )'
  passing x.xmlrecord 
  columns
    "CONTRACT.DATE" date path 'c1',
    "VALUE.DATE" date path 'c2',
    "PAYMENT.START.DATE" date path 'c5',
    "MATURITY.DATE" date path 'c6',
    "BILL.PAY.DATE" date path 'c12',
    "BILL.ID" varchar2(20) path 'c13'
) xt;
我想您也可以使用XLST转换来实现这一点,但我对这些并不太熟悉

使用添加到问题中的示例XML的稍微精简版本,以下代码得到:

CONTRACT. VALUE.DAT PAYMENT.S MATURITY. BILL.PAY. BILL.ID             
--------- --------- --------- --------- --------- --------------------
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-SEP-13 AABILL13265WLWSR    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-OCT-13 AABILL13295PD9RK    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-NOV-13 AABILL133263FXPS    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-DEC-13 AABILL133568M6DK    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-JAN-14 AABILL14022VH2JB    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-FEB-14 AABILL14053G95RF    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-MAR-14 AABILL140814YYC3    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-APR-14 AABILL14112M0MZ4    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-MAY-14 AABILL14142RRH3P    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-JUN-14 AABILL14173D6GZJ    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-JUL-14 AABILL14203HY9V6    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-AUG-14 AABILL142341G2BW    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-SEP-14 AABILL142651P9D9    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-OCT-14 AABILL14295FC8G1    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-NOV-14 AABILL14326LY4DN    
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 27-DEC-14 AABILL14356GTNDX    
但该编辑还提到将所有账单值作为一个XML片段获取,因此您还可以执行以下操作:

select xt.*
from t24.fbnk_aa_account_details x
cross join xmltable('/row'
  passing x.xmlrecord 
  columns
    "CONTRACT.DATE" date path 'c1',
    "VALUE.DATE" date path 'c2',
    "PAYMENT.START.DATE" date path 'c5',
    "MATURITY.DATE" date path 'c6',
    "BILL.PAY.DATE" xmltype path 'c12',
    "BILL.ID" xmltype path 'c13'
) xt;
这会生成笨拙的包装以供显示!:

CONTRACT. VALUE.DAT PAYMENT.S MATURITY. BILL.PAY.DATE                                                                    BILL.ID                                                                         
--------- --------- --------- --------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 <c12>20130927</c12><c12 m="2">20131027</c12><c12 m="3">20131127</c12><c12 m="4"> <c13>AABILL13265WLWSR</c13><c13 m="2">AABILL13295PD9RK</c13><c13 m="3">AABILL133
                                        20131227</c12><c12 m="5">20140127</c12><c12 m="6">20140227</c12><c12 m="7">20140 263FXPS</c13><c13 m="4">AABILL133568M6DK</c13><c13 m="5">AABILL14022VH2JB</c13><
                                        327</c12><c12 m="8">20140427</c12><c12 m="9">20140527</c12><c12 m="10">20140627< c13 m="6">AABILL14053G95RF</c13><c13 m="7">AABILL140814YYC3</c13><c13 m="8">AABI
                                        /c12><c12 m="11">20140727</c12><c12 m="12">20140827</c12><c12 m="13">20140927</c LL14112M0MZ4</c13><c13 m="9">AABILL14142RRH3P</c13><c13 m="10">AABILL14173D6GZJ<
                                        12><c12 m="14">20141027</c12><c12 m="15">20141127</c12><c12 m="16">20141227</c12 /c13><c13 m="11">AABILL14203HY9V6</c13><c13 m="12">AABILL142341G2BW</c13><c13 m=
                                        >                                                                                "13">AABILL142651P9D9</c13><c13 m="14">AABILL14295FC8G1</c13><c13 m="15">AABILL1
                                                                                                                         4326LY4DN</c13><c13 m="16">AABILL14356GTNDX</c13>                               

其他选项是聚合来自上一个查询的值;或者每m值有一对列,假设有一个合理的上限,可以直接在XMLTable调用中进行,也可以稍后通过数据透视进行;或者每个日期/ID将账单信息处理到一个新节点中,并以XML格式返回所有这些信息。。。这取决于您实际需要的输出。

包含一个XML记录的示例可能会有所帮助;你的编辑说想要它们,但现在只有c13?一排,但没有解释怎么做。您提到了XML,但不清楚这是您想要的还是您认为必须拥有的,或者它应该采取什么形式。请澄清,并显示您希望为该样本数据实现的输出。不,我希望c12在不同的列中,c13也在不同的列中。很抱歉,我无法正确解释这些问题。
select xt.*
from t24.fbnk_aa_account_details x
cross join xmltable('/row'
  passing x.xmlrecord 
  columns
    "CONTRACT.DATE" date path 'c1',
    "VALUE.DATE" date path 'c2',
    "PAYMENT.START.DATE" date path 'c5',
    "MATURITY.DATE" date path 'c6',
    "BILL.PAY.DATE" xmltype path 'c12',
    "BILL.ID" xmltype path 'c13'
) xt;
CONTRACT. VALUE.DAT PAYMENT.S MATURITY. BILL.PAY.DATE                                                                    BILL.ID                                                                         
--------- --------- --------- --------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
24-AUG-13 24-AUG-13 27-SEP-13 31-AUG-38 <c12>20130927</c12><c12 m="2">20131027</c12><c12 m="3">20131127</c12><c12 m="4"> <c13>AABILL13265WLWSR</c13><c13 m="2">AABILL13295PD9RK</c13><c13 m="3">AABILL133
                                        20131227</c12><c12 m="5">20140127</c12><c12 m="6">20140227</c12><c12 m="7">20140 263FXPS</c13><c13 m="4">AABILL133568M6DK</c13><c13 m="5">AABILL14022VH2JB</c13><
                                        327</c12><c12 m="8">20140427</c12><c12 m="9">20140527</c12><c12 m="10">20140627< c13 m="6">AABILL14053G95RF</c13><c13 m="7">AABILL140814YYC3</c13><c13 m="8">AABI
                                        /c12><c12 m="11">20140727</c12><c12 m="12">20140827</c12><c12 m="13">20140927</c LL14112M0MZ4</c13><c13 m="9">AABILL14142RRH3P</c13><c13 m="10">AABILL14173D6GZJ<
                                        12><c12 m="14">20141027</c12><c12 m="15">20141127</c12><c12 m="16">20141227</c12 /c13><c13 m="11">AABILL14203HY9V6</c13><c13 m="12">AABILL142341G2BW</c13><c13 m=
                                        >                                                                                "13">AABILL142651P9D9</c13><c13 m="14">AABILL14295FC8G1</c13><c13 m="15">AABILL1
                                                                                                                         4326LY4DN</c13><c13 m="16">AABILL14356GTNDX</c13>