Oracle XQuery удалить, вставить, обновить - PullRequest
0 голосов
/ 08 ноября 2018

Все ниже, что я могу сделать в отдельных операциях, но, поскольку я относительно новичок в 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  
      )    ;

Однако я хотел бы, чтобы мой запрос удалил все существующие узлы MMGroupID из целевого XML (если они существуют), а затем заменил их всеми узлами из исходного 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 Ответ

0 голосов
/ 08 ноября 2018

Для синтаксиса вы должны Google для XQuery Update Facility.
Пример

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