【问题标题】:How to update xml element in clob oracle having no root element如何更新没有根元素的clob oracle中的xml元素
【发布时间】: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';

【问题讨论】:

    标签: plsql plsqldeveloper


    【解决方案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()。你在跑什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    相关资源
    最近更新 更多