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