2017-06-20 50 views
0

我在文件夾下面有XML,我想查找並替換一些值。怎麼做?將值更新到ORACLE中的XML 10G

示例:無論哪裏UK0都在那裏,我想用UPDATE QUERY替換UK1。

<?xml version="1.0"?> 
<RSET> 
<ROW> 
    <SDC_FNAME>JQ13868001.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK0</SDC_TO> 
</ROW> 
<ROW> 
    <SDC_FNAME>JQ13868002.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK0</SDC_TO> 
</ROW> 
</RSET> 

回答

0

在10g中,你可以使用the updatexml() function

select updatexml(your_xml, '/RSET/ROW/SDC_TO[text()="UK0"]/text()', 'UK1') 
from ... 

演示(在11gR2的運行使用的xmlserialize()indent條款,只是爲了讓它更漂亮;在updatexml()部分10gR2中工作):

select xmlserialize(content 
    updatexml(xmltype('<?xml version="1.0"?> 
<RSET> 
<ROW> 
    <SDC_FNAME>JQ13868001.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK0</SDC_TO> 
</ROW> 
<ROW> 
    <SDC_FNAME>JQ13868002.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK1</SDC_TO> 
</ROW> 
</RSET>'), '/RSET/ROW/SDC_TO[text()="UK0"]/text()', 'UK1') 
    indent) as result 
from dual; 

RESULT                   
-------------------------------------------------------------------------------- 
<?xml version="1.0"?> 
<RSET> 
    <ROW> 
    <SDC_FNAME>JQ13868001.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK1</SDC_TO> 
    </ROW> 
    <ROW> 
    <SDC_FNAME>JQ13868002.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK1</SDC_TO> 
    </ROW> 
</RSET> 

該函數在稍後的版本中不推薦使用N,所以 (假設這個作品在10g中,這是我現在無法驗證) 從11g中,您應該使用XQuery來代替:

select xmlquery(' 
    copy $i := $p modify (
    for $j in $i/RSET/ROW/SDC_TO[text()="UK0"] 
     return replace value of node $j with "UK1" 
    ) 
    return $i' 
    passing your_xml AS "p" 
    returning content) 
from ... 

但語法不10gR2中支持。

演示反正(11gR2的下運行):

select xmlserialize(content xmlquery(' 
    copy $i := $p modify (
    for $j in $i/RSET/ROW/SDC_TO[text()="UK0"] 
     return replace value of node $j with "UK1" 
    ) 
    return $i' 
    passing xmltype('<?xml version="1.0"?> 
<RSET> 
<ROW> 
    <SDC_FNAME>JQ13868001.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK0</SDC_TO> 
</ROW> 
<ROW> 
    <SDC_FNAME>JQ13868002.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK1</SDC_TO> 
</ROW> 
</RSET>') AS "p" 
    returning content) indent) as result 
from dual; 

RESULT                   
-------------------------------------------------------------------------------- 
<?xml version="1.0"?> 
<RSET> 
    <ROW> 
    <SDC_FNAME>JQ13868001.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK1</SDC_TO> 
    </ROW> 
    <ROW> 
    <SDC_FNAME>JQ13868002.XML</SDC_FNAME> 
    <SDC_RECORD>6</SDC_RECORD> 
    <SDC_FROMDT>06/14/2017 08:13:58</SDC_FROMDT> 
    <SDC_TODT>06/16/2017 08:13:58</SDC_TODT> 
    <SDC_TNAME>S_STYLE</SDC_TNAME> 
    <SDC_FROM>AB</SDC_FROM> 
    <SDC_TO>UK1</SDC_TO> 
    </ROW> 
</RSET> 
+0

非常感謝.... –

+0

是否有可能使用.BAT(批處理文件) –

+0

@dkoothan - 你可以有一個批處理文件運行的腳本通過SQL \ * Plus。有很多例子。假設你在某些時候將XML加載到Oracle中(或者爲什麼涉及Oracle在這裏呢?),所以這可以用來更新已經在表中的值,用'update your_table set your_xml = updatexml(your_xml,... )'。如果XML不在數據庫中,那麼您可以查看SQL \ * Loader或[external tables](https://docs.oracle.com/cd/B19306_01/server.102/b14215/et_concepts.htm)。嘗試通過批處理腳本插入超過4k的值是有點痛苦。 –