Oracle XQuery删除,插入,更新

时间:2018-11-08 08:40:20

标签: oracle xquery

下面的所有内容我都可以在单独的操作中完成,但是由于我对XQuery比较陌生,因此我正在努力研究如何一次性执行多项操作,这很简洁。

我正在尝试使用另一个列中的一些xml数据来更新XML列(此XML来自具有两列,促销编号和每个促销内的部门编号的电子表格)。我将其加载到表格中,然后针对以下内容运行。

datetime.py

创建一个包含PROMID列和一个XML列的表,如下所示(为便于阅读,示例中只有一个MMGroup。

INSERT INTO proms
select promid,  '<Promotion><MultibuyGroup><MMGroupID>'||depts||'</MMGroupID> 
</MultibuyGroup></Promotion>' DEPTS
from (
     SELECT promid, listagg (id,'</MMGroupID><MMGroupID>')  within GROUP 
 (ORDER BY id) as depts FROM mmgroups 
 GROUP BY promid
 );

当我运行以下命令时,我可以成功更新PROMOTIONS中的任何XML,其中ID列的值与我​​在上面创建的表中的PROMID的值匹配。

   <Promotion><MultibuyGroup><MMGroupID>1</MMGroupID></Promotion></MultibuyGroup>

但是,我希望查询执行的操作是从目标xml中删除任何现有的MMGroupID节点(如果存在),然后将其替换为源xml中的所有节点。

目标xml中还有一个LastUpdated节点,我想在更新时使用SYSDATE进行更新

另外两个具有更新时间的列LAST_UPDATED DATE和ROW_UPDATED NUMBER(20,0)可以很好地同时更新。

merge into PROMOTIONS tgt  
using (  
 select PROMID 
      , xmlquery('/Promotion/MultibuyGroup/MMGroupID'  
          passing xmlparse(document DEPTS)  
          returning content  
        ) as new_mmg  
 from PROMS WHERE PROMID  = 'EMP35Level1'

) src  
 on (tgt.ID = src.PROMID)  

 when matched then update  
  set tgt.xml =  
     xmlserialize(document  
       xmlquery(  
         'copy $d := .  
         modify             
          insert node $new_mmg as last into  $d/Promotion/MultibuyGroup 
          return $d'  
          passing xmlparse(document tgt.xml)  
                 , src.new_mmg as "new_mmg"  
         returning content  
        )  
       no indent  
      )    ;

自发布以来,已将查询编辑为:

        <Promotion>
        <LastUpdated>2018-08-23T14:56:35+01:00</LastUpdated>
        <MajorVersion>1</MajorVersion>
        <MinorVersion>52</MinorVersion>
        <PromotionID>EMP35Level1</PromotionID>
        <Description enabled="1">Staff Discount 15%</Description>
        <MultibuyGroup>
            <AlertThresholdValue>0.0</AlertThresholdValue>
            <AlertThresholdValue currency="EUR">0.0</AlertThresholdValue>
            <UseFixedValueInBestDeal>0</UseFixedValueInBestDeal>
            <UpperThresholdValue>0.0</UpperThresholdValue>
            <UpperThresholdValue currency="EUR">0.0</UpperThresholdValue>
            <GroupDescription>Employee Discount 15%</GroupDescription>
            <Rolling>0</Rolling>
            <DisableOnItemDiscount>1</DisableOnItemDiscount>
            <UniqueItems>0</UniqueItems>
            <AllItems>0</AllItems>
            <RoundingRule>3</RoundingRule>
            <UseLowestNetValue>0</UseLowestNetValue>
            <TriggerOnLostSales>0</TriggerOnLostSales>
            <MMGroupID>2</MMGroupID>
            <MMGroupID>8</MMGroupID>
            <MMGroupID>994</MMGroupID>
        </MultibuyGroup>
        <Timetable>
            <XMLSchemaVersion>1</XMLSchemaVersion>
            <CriterionID/>
            <StartDate>1970-01-01T00:00:00+00:00</StartDate>
            <FinishDate>2069-12-31T00:00:00+00:00</FinishDate>
        </Timetable>
        <AllowedForEmployeeSale>1</AllowedForEmployeeSale>
        <Notes enabled="1"/>
        <AlertMessage enabled="1"/>
    </Promotion>

非常正确,除了我需要

 merge INTO PROMOTIONS3 tgt
     using (
     SELECT PROMID
           ,xmlquery('/Promotion/MultibuyGroup/MMGroupID'
             passing xmlparse(document DEPTS)
             returning content
                      ) as new_mmg
       FROM PROMS WHERE PROMID  = 'EMP35Level1'
            ) src
       ON (tgt.ID = src.PROMID)
       when matched then update
       SET tgt.xml =
          xmlserialize(document
            xmlquery(
              'copy $d := .
               modify(
               delete nodes  $d/Promotion/MultibuyGroup/MMGroupID,
               insert node $new_mmg as last into  $d/Promotion/MultibuyGroup,
               replace value of node  $d/Promotion/LastUpdated with current-dateTime())
               return $d'
               passing xmlparse(document tgt.xml)
                      ,src.new_mmg as "new_mmg"
               returning content
                    )
             no indent
                        )
            ,last_updated = (SELECT SYSDATE FROM dual)
            ,row_updated = (SELECT ( SYSDATE - To_date('01-01-1970 00:00:00','DD-MM-YYYY HH24:MI:SS') ) *  24 * 60  * 60 * 1000 FROM dual) ;

不是

 <LastUpdated>2018-08-23T14:56:35+01:00</LastUpdated>

所以我需要弄清楚。

干杯。

1 个答案:

答案 0 :(得分:1)

对于语法,您应该通过Google搜索XQuery更新工具。
一个例子

xmlquery(  
'copy $d := .  
     modify(         
         delete nodes  $d/Promotion/MMGroupID,
         replace value of node  $d/Promotion/LastUpdated with current-date(),
         insert node <node1>x</node1> as last into  $d/Promotion/MultibuyGroup,
         insert node <node2>x</node2> as last into  $d/Promotion/MultibuyGroup) 
      return $d 
'