2013-05-30 61 views
1

我想實現是創建一個包含所有爲這個特定的XML多項目的子節點單獨行的表:構建的XMLType查詢到Oracle11g的存儲數據

<ABCD> 
<EMPLOYEE id="11" date="25-Apr-1983"> 
<NameDetails> 
<Name NameType="a"> 
<NameValue> 
<FirstName>ABCD</FirstName> 
<Surname>PQR</Surname> 
<OriginalName>TEST1</OriginalName> 
<OriginalName>TEST2</OriginalName> 
</NameValue> 
</Name> 
<Name NameType="b"> 
<NameValue> 
<FirstName>TEST3</FirstName> 
<Surname>TEST3</Surname> 
</NameValue> 
<NameValue> 
<FirstName>TEST5</FirstName> 
<MiddleName>TEST6</MiddleName> 
<Surname>TEST7</Surname> 
<OriginalName>JAB1</OriginalName> 
</NameValue> 
<NameValue> 
<FirstName>HER</FirstName> 
<MiddleName>HIS</MiddleName> 
<Surname>LOO</Surname> 
</NameValue> 
</Name> <Name NameType="c"> 
<NameValue> 
<FirstName>CDS</FirstName> 
<MiddleName>DRE</MiddleName> 
<Surname>QWE</Surname> 
</NameValue> 
<NameValue> 
<FirstName>CCD</FirstName> 
<MiddleName>YTD</MiddleName> 
<Surname>QQA</Surname> 
</NameValue> 
<NameValue> 
<FirstName>DS</FirstName> 
<Surname>AzDFz</Surname> 
</NameValue> 
</Name> 
</NameDetails> 

</EMPLOYEE > 
</ABCD> 

我使用查詢嘗試:

SELECT t.personid,n.nametypeid,t.firstname,t.middlename,t.surname,t.maidenname,t.originalName 
FROM xml_files p,master_nametypes n, 
    XMLTable(
     'for $i in ADCD/Employee/NameDetails/Name/NameValue 
     return <row> 
     { 
      $i/../../../@id, 
      $i/../@NameType, 
      $i/FirstName, 
      $i/MiddleName, 
      $i/OriginalName 
      $i/Surname, 
      $i/MaidenName, 
      $i/Suffix, 
      $i/SingleStringName, 
      $i/EntityName 

     } 
     </row>' 
     PASSING p.filecontent 
     COLUMNS 
       personid number PATH '@id', 
       nametypeid VARCHAR2(255) PATH '@NameType', 
       firstname VARCHAR2(4000) PATH 'FirstName', 
       middlename VARCHAR2(4000) PATH 'MiddleName', 
       surname VARCHAR2(4000) PATH 'Surname', 
       maidenname VARCHAR2(4000) PATH 'MaidenName', 
       originalName VARCHAR2(4000) PATH '.' 

      ) t where t.nametypeid = n.nametype and n.recordtype = 'Employee' 
; 

但是,當有一個像在「NAMEVALUE」節點「ORIGINALNAME」多個子節點,這將拋出錯誤。我如何根據父節點在單獨的行中檢索這些值。有人可以幫我糾正這個問題。任何幫助,將不勝感激。

回答

0

試試這個:

SQL> SELECT t.personid, t.firstname, t.middlename, 
    2   t.surname,t.maidenname, 
    3   replace(replace(t.originalName, '<OriginalName>'), 
    4     '</OriginalName>', ' ') originalName 
    5 FROM xml_files p, 
    6  XMLTABLE (
    7  --'ABCD/EMPLOYEE/NameDetails/Name/NameValue' 
    8  'for $i in ABCD/EMPLOYEE/NameDetails/Name/NameValue 
    9   return <row> 
10     {$i/../../../@id} 
11     {$i/../@NameType} 
12     {$i/FirstName}{$i/MiddleName}{$i/OriginalName} 
13     {$i/Surname}{$i/MaidenName} 
14    </row>' 
15  PASSING p.filecontent 
16  COLUMNS 
17    personid  NUMBER   PATH '@id', 
18    nametypeid VARCHAR2(255) PATH '@NameType', 
19    firstname VARCHAR2(4000) PATH 'FirstName', 
20    middlename VARCHAR2(4000) PATH 'MiddleName', 
21    surname  VARCHAR2(4000) PATH 'Surname', 
22    maidenname VARCHAR2(4000) PATH 'MaidenName', 
23    originalName XMLTYPE  PATH 'OriginalName' 
24    ) t; 

    PERSONID FIRSTNAME MIDDLENAME SURNAME MAIDENNAME ORIGINALNAME 
---------- ---------- ----------- -------- ----------- ------------ 
     11 ABCD     PQR     TEST1 TEST2 
     11 TEST3     TEST3     
     11 TEST5  TEST6  TEST7    JAB1 
     11 HER  HIS   LOO     
     11 CDS  DRE   QWE     
     11 CCD  YTD   QQA     
+0

非常感謝文森特。這工作..但我想多個「OriginalName」是在兩個不同的行,而不是顯示在一行。我可以如何修改這個來實現。 – Kiran

1

您也可以嘗試這樣的事情(這將解除規範化的表格):

Here is a sqlfiddle demo

SELECT t.personid,t.nametypeid,t.firstname,t.middlename,t.surname,t.maidenname,t.originalName 
FROM xml_files p, 
    XMLTable(
     ' 
     for $m in $ADCD//NameValue/OriginalName 
     | $ADCD//NameValue[not(exists(OriginalName))] 
     return 
     <row> 
     { 
      ($m/../../../../@id , $m/../../../@id)[1], 
      ($m/../../@NameType,$m/../@NameType)[1], 
      ($m/../FirstName,$m/FirstName)[1], 
      ($m/../MiddleName,$m/MiddleName)[1], 
      ($m,"")[1], 
      ($m/../Surname,$m/Surname)[1], 
      ($m/../MaidenName,$m/MaidenName)[1], 
      ($m/../Suffix,$m/Suffix)[1], 
      ($m/../SingleStringName,$m/SingleStringName)[1], 
      ($m/../EntityName,$m/EntityName)[1] 
     } 
     </row>' 

     PASSING p.filecontent as "ADCD" 
     COLUMNS 

       personid number PATH '@id', 
       nametypeid VARCHAR2(255) PATH '@NameType', 
       firstname VARCHAR2(4000) PATH 'FirstName', 
       middlename VARCHAR2(4000) PATH 'MiddleName', 
       surname VARCHAR2(4000) PATH 'Surname', 
       maidenname VARCHAR2(4000) PATH 'MaidenName', 
       originalName VARCHAR2(4000) PATH 'OriginalName' 


      ) t 
; 
+0

非常感謝A.B.爲你的時間..但是當我嘗試,這並沒有給我任何resullt。它給我零行作爲輸出。我不知道爲什麼是這樣。 – Kiran

+0

在演示中,它的工作原理,所以它可能是xpath中的一些東西,因爲我做了一些「快捷方式」...... –

+0

嗨A.B ..我試着在演示中給出了正確的xpath和所有,它在那裏完美的工作。但是,當我嘗試使用SQL開發者3.2.09時,相同的代碼不會爲相同的數據獲取任何結果。我不知道這是爲什麼。 :( – Kiran