2017-06-20 61 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的值是有点痛苦。 –