如何更新没有根元素的clob oracle中的xml元素

Posted

技术标签:

【中文标题】如何更新没有根元素的clob oracle中的xml元素【英文标题】:How to update xml element in clob oracle having no root element 【发布时间】:2018-04-19 12:06:04 【问题描述】:

我想更新 oracle 的 clob 列中的特定 xml 元素值。 xml如下

<TraceOn>NO</TraceOn>
<isDateTimePopulated>NO</isDateTimePopulated>
<serviceProvider>LWS</serviceProvider>
<AutomatedRetry>YES</AutomatedRetry>
<retryDateTime>2018-08-29-18.15.07</retryDateTime>

此数据没有根元素,我尝试通过以下查询更新 retryDateTime 但它不起作用。

update READ_DATA p1 
set p1.bo_data = to_clob(updatexml(xmltype(p1.bo_data),
                 '/retryDateTime/text()','2018-08-29-18.15.07') )
 where INIT_MSRMT_DATA_ID='57610034614521';

【问题讨论】:

【参考方案1】:

1) 通过添加根节点使 xml 格式良好。

2) 使用 xquery 更新节点(不推荐使用 updatexml)

3) 只返回根的孩子

select xmlserialize(content xmlquery( 'copy $tmp := $xml_data modify 
    (for $i in $tmp/root/retryDateTime
               return replace value of node $i with $value)
               return $tmp/root/*'
passing  xmltype('<root>'||'<TraceOn>NO</TraceOn>
<isDateTimePopulated>NO</isDateTimePopulated>
<serviceProvider>LWS</serviceProvider>
<AutomatedRetry>YES</AutomatedRetry>
<retryDateTime>2018-08-29-18.15.07</retryDateTime>'||'</root>') as "xml_data", 'new node value' as "value" returning content) as clob indent size = 2)  from dual;

有用的例子https://docs.oracle.com/database/121/ADXDB/app_depr_upd.htm#ADXDB6044

【讨论】:

该死..你很快:) @Arkadiusz ... 使用给定的 SQL 我能够更新 xml 元素。感谢您的帮助。 :)【参考方案2】:

大多数 XML-Function 需要在 SQL 而不是 plsql 中使用。

这里是一步一步的:

DECLARE
    myClob   VARCHAR2 (4000) := '<TraceOn>NO</TraceOn>
<isDateTimePopulated>NO</isDateTimePopulated>
<serviceProvider>LWS</serviceProvider>
<AutomatedRetry>YES</AutomatedRetry>
<retryDateTime>2018-08-29-18.15.07</retryDateTime>';

    myXml    XMLTYPE;
    tmp      VARCHAR2 (4000);
    tmpDate  Date;
BEGIN
    DBMS_OUTPUT.put_line (' - - - build valid xml, by adding a root - - - ');
    myXml := XMLTYPE.CREATEXML ('<faketag>' || myClob || '</faketag>');

    DBMS_OUTPUT.put_line (myXml.getClobVal ());

    DBMS_OUTPUT.put_line (' - - - extract the desired tag - - - ');

    SELECT EXTRACTVALUE (myXml, '/faketag/retryDateTime') INTO tmp FROM DUAL; -- EXTRACTVALUE is ONLY allowed in SQL not PL/SQL! We need a select-into
    DBMS_OUTPUT.put_line (tmp);
    DBMS_OUTPUT.put_line (' - - - Extract the date to check the value and work with it - - - ');

    tmpDate := to_date(tmp,'yyyy-mm-dd-HH24.MI.SS');
    dbms_output.put_line('MyDate: ' || tmpDate); 

    dbms_output.put_line(' - - - update our xml - - - ');
    select updateXML(myXml, '/faketag/retryDateTime', '2017-01-01-13.59.59') into myXml from dual; -- updateXML is ONLY allowed in SQL not PL/SQL! We need a select-into
    DBMS_OUTPUT.put_line (myXml.getClobVal ());

    dbms_output.put_line(' - - - now it''s you turn ;) - - - '); 
END;

【讨论】:

感谢您的快速回复。我尝试执行您的代码,它对我来说效果很好,在下面的行中几乎没有更正。从 dual 中选择 updateXML(myXml, '/faketag/retryDateTime', '2017-01-01-13.59.59') 进入 myXml; ---- 修正完成 -- '/faketag/retryDateTime/text()' 嗯...在我的 12c 数据库上工作,有无 /test()。你在跑什么?

以上是关于如何更新没有根元素的clob oracle中的xml元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 CLOB 值更新 oracle 中的 clob 列

php如何读取clob字段

使用 Mybatis 3 更新 Oracle CLOB 有啥技巧吗?

oracle中怎样修改varchar2字段为clob字段

如何从 Oracle JSON CLOB 类型的 JSON 数组中选择特定元素

DB2中如何将一个clob类型的字段改为varchar类型