代码之家  ›  专栏  ›  技术社区  ›  DanBot

Oracle XQuery删除、插入、更新

  •  1
  • DanBot  · 技术社区  · 7 年前

    下面的所有操作我都可以在单独的操作中完成,但是由于我对XQuery还比较陌生,所以我正在努力研究如何一次执行多个操作,这将是很好的。

    我正在尝试用来自另一列的一些XML数据更新XML列(这个XML来自一个包含两列的电子表格,促销编号和每个促销中的部门编号)。我把它放在一张桌子上,然后把下面的东西放在上面。

    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
     );
    

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

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

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

    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  
          )    ;
    

    然而,我希望我要做的是从目标XML中删除任何现有的MMGCUPID节点(如果它们存在),然后用源XML中的所有节点替换它们。

    目标xml中还有一个LastUpdated节点,我希望在更新时用SYSDATE更新它

    还有两个独立的列LAST_UPDATED DATE和ROW_UPDATED NUMBER(20,0),这两个列具有更新的纪元时间,最好同时更新。

            <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>
    

    不是

      <LastUpdated>2018-11-09T11:53:10.591000+00:00</LastUpdated>
    

    所以我需要弄清楚。

    干杯。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Arkadiusz Łukasiewicz    7 年前

    对于语法,您应该使用google For 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 
    '
    
    推荐文章