2011-06-30 88 views
3

我正在使用oracle 11g r2數據庫,基本上需要能夠解析並從中選擇一些節點。我花了幾個小時瀏覽網絡並閱讀oracle xml db手冊,試圖找到適合我的問題的解決方案,但我似乎無法確定這樣做的正確方法。我有一定的程序設計經驗,但一般都沒有使用xml,sql或oracle數據庫,所以如果這是一個微不足道的問題,請原諒我。如何從以前的XML查詢結果中進行選擇

好等方面的問題:

我有保存的catalog.xml一個非常簡單的XML文件,並將其計算方法如下:

<catalog> 
    <cd> 
     <title>Hide your heart</title> 
     <artist>Bonnie Tyler</artist> 
     <country>UK</country> 
     <company>CBS Records</company> 
     <price>9.90</price> 
     <year>1988</year> 
    </cd> 
    <cd> 
     <title>Empire Burlesque</title> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company>Columbia</company> 
     <price>10.90</price> 
     <year>1985</year> 
    </cd> 
</catalog> 

現在我希望能夠提取標題的CD給予某個藝術家。因此,舉例來說,如果藝術家是「鮑勃·迪倫」,那麼標題應該是「帝國的滑稽戲」

現在我在Oracle中創建的XMLType表如下:

CREATE TABLE BINARY OF XMLType XMLTYPE STORE AS BINARY XML; 

我然後繼續加載我xml文件導入oracle通過:

insert into BINARY values (XMLTYPE(BFILENAME ('XML_DIR','catalog.xml'),nls_charset_id('AL32UTF8'))); 

到目前爲止好。

現在的提取部分:

首先我想:

SELECT extract(b.object_value, '/catalog/cd/title') 
FROM binary b 
WHERE existsNode(b.object_value,'/catalog/cd[artist="Bob Dylan"]') = 1; 

EXTRACT(B.OBJECT_VALUE,'/CATALOG/CD/TITLE') 
-------------------------------------------------------------------------------- 

<Title>Hide your heart</Title> 
<Title>Empire Burlesque</Title> 

1 row selected. 

這並沒有工作,因爲XML文件是所有爲1行,所以我意識到,我不得不分割我的xml到單獨的行。這樣做,我必須使用XMLSequence()和table()函數將節點轉換爲虛擬表。這些函數將由extract()返回的兩個標題節點轉換爲由兩個XMLType對象組成的虛擬表格,每個對象包含一個標題元素。

第二個嘗試:

SELECT value(d) 
FROM binary b, 
table (xmlsequence(extract(b.object_value,'/catalog/cd'))) d 
WHERE existsNode(b.object_value,'/catalog/cd[artist="Bob Dylan"]') = 1; 

VALUE(D) 
-------------------------------------------------------------------------------- 

<cd> 
    <title>Hide your heart</title> 
    <artist>Bonnie Tyler</artist> 
    <country>UK</country> 
    <company>CBS Records</company> 
    <price>9.90</price> 
    <year>1988</year> 
</cd> 

<cd> 
    <title>Empire Burlesque</title> 
    <artist>Bob Dylan</artist> 
    <country>USA</country> 
    <company>Columbia</company> 
    <price>10.90</price> 
    <year>1985</year> 
</cd> 

2 rows selected. 

這是更好,因爲它現在被分成2個不同行,所以我應該可以做一個選擇,其中選擇基於藝術家稱號。

但是,這是我遇到問題,我已經嘗試了幾個小時,但我無法弄清楚如何在我的下一個使用上述查詢的結果。所以我試圖這樣做是爲了使用suquery:

select extract(sub1, 'cd/title') 
from 
(
    SELECT value(d) 
    FROM binary b, 
    table (xmlsequence(extract(b.object_value,'/catalog/cd'))) d 
) sub1 
WHERE existsNode(sub1,'/cd[artist="Bob Dylan"]') = 1; 

然而,在SQL * Plus顯示了一個錯誤:

ORA-00904: "SUB1": invalid identifier. 

我試過幾十試圖使用子查詢的變化,但我的模擬似乎無法做到。

我聽說你也可以做這個使用變量或PL/SQL,但我不知道從哪裏開始。

任何幫助將不勝感激,因爲我已經嘗試了一切在我的處置。

回答

1

這應該工作:

SELECT EXTRACTVALUE (VALUE(xml), '*/title') title 
    FROM TABLE (XMLSEQUENCE (EXTRACT (XMLTYPE (' 
     <catalog> 
     <cd> 
      <title>Hide your heart</title> 
      <artist>Bonnie Tyler</artist> 
      <country>UK</country> 
      <company>CBS Records</company> 
      <price>9.90</price> 
      <year>1988</year> 
     </cd> 
     <cd> 
      <title>Empire Burlesque</title> 
      <artist>Bob Dylan</artist> 
      <country>USA</country> 
      <company>Columbia</company> 
      <price>10.90</price> 
      <year>1985</year> 
     </cd> 
     </catalog>'), '/catalog/cd'))) xml 
WHERE EXTRACTVALUE (VALUE(xml), '*/artist') = 'Bob Dylan'; 

或使用表:

SELECT EXTRACTVALUE (VALUE(xml), '*/title') title 
    FROM binary b, 
     TABLE (XMLSEQUENCE (EXTRACT (b.object_value, '/catalog/cd'))) xml 
WHERE EXTRACTVALUE (VALUE(xml), '*/artist') = 'Bob Dylan'; 

這是什麼東西做的是提取所有cd節點到虛擬表xml,每個cd返回一個結果行存在的節點。 WHERE子句然後通過查看子元素artist ='Bob Dylan'和 SELECT語句只分析出title元素的內容而不是顯示整個節點來限制結果。

的輸出是:

TITLE 
---------------- 
Empire Burlesque 
相關問題