Oracle XQuery 删除、插入、更新

标签 oracle xquery

下面的所有内容我都可以在单独的操作中完成,但由于我对 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>

当我运行下面的代码时,我可以成功更新 PROMOTIONS 中的任何 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 中删除任何现有的 MMGroupID 节点(如果存在),然后将它们替换为源 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>

所以我需要弄清楚这一点。

干杯。

最佳答案

对于语法,您应该搜索 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 
'

关于Oracle XQuery 删除、插入、更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53204101/

相关文章:

在xquery中分割逗号分隔的字符串?

xml - 返回表达式中的XQuery变量未解析其值

sql - Mysql中的异或约束

java - 使用 PL/SQL 调用使用 JDBC 连接到 SQL Server 数据库的 java 方法

sql - Oracle - 按条件查找列之间的差异

sql - 在oracle中将两行连接成一行(不同列)

maven - 如何在 xquery 中访问环境变量?

xpath - Marklogic - 如何处理 XML 中的处理指令

python - ORA-01722 : invalid number - Python with cx_Oracle

xml - XQuery 嵌套返回