我有一个表(Table 1),它有一个XMLType字段(PROPERTIES),还有一个表(Table 2),它有两个字段:
- 标签名称
- TAG_RENAME
每个XMLType记录可以有不同的标记名。我需要得到的选择输出,与标签重命名的XMLType字段(我不需要更新字段)。
这里有一个例子:
表1:
| ID|产品展示|
| - -----|- -----|
| 1| </Fields><TAG1>123</TAG1><TAG2>345</TAG2></Fields>
|
| 2| </Fields><TAG1>999</TAG1><TAG3>XXX</TAG3></Fields>
|
表2:
| 标签名称|TAG_RENAME|
| - -----|- -----|
| TAG1|新闻_TAG1|
| TAG2|新闻_TAG2|
| TAG3|新闻_TAG3|
所需输出:
| ID|新_属性|
| - -----|- -----|
| 1| </Fields><NEW_TAG1>123</NEW_TAG1><NEW_TAG2>345</NEW_TAG2></Fields>
|
| 3| </Fields><NEW_TAG1>999</NEW_TAG1><NEW_TAG3>XXX</NEW_TAG3></Fields>
|
我用这种方式尝试了XQuery(左连接,因为一些PROPERTIES字段可以是NULL):
select t.ID, t.tag_name, t.value FROM Table1 t
left join XMLTable ('for $i in fn:collection("oradb:/MY_USER/TABLE2"), $x in //descendant::*
where $i/ROW/TAG_NAME=local-name($x)
return element r {
element tag_name {$i/ROW/TAG_RENAME/text()}
, element tag_value {$x/text()}
}'
passing case when t.properties is null then null else xmltype ('<?xml version="1.0" encoding="iso-8859-1" ?>'||t.properties)end
columns tag_name varchar2(30) path 'tag_name',
tag_value varchar2(30) path 'tag_value'
)x on 1=1 and x.tag_value is not null;
我得到的输出
| ID|标签名称|标签值|
| - -----|- -----|- -----|
| 1|新闻_TAG1|一百二十三|
| 1|新闻_TAG2|三百四十五|
| 2|新闻_TAG1|九九九|
| 2|新闻_TAG3| XXX|
所以它几乎起作用了。问题是我希望每个ID都在一行上。我试过listagg,它的工作,但它的速度很慢。有没有办法直接在XQuery中重命名TAG?
2条答案
按热度按时间dzhpxtsq1#
您可以使用XQuery来修改XML。
| ID|瓦尔|重新命名|
| - -----|- -----|- -----|
| 1|123345|<NEW_TAG1>123345</NEW_TAG1><NEW_TAG2></NEW_TAG2>|
| 2|小行星999|小<NEW_TAG1></NEW_TAG1><NEW_TAG3>行星999</NEW_TAG3>|
fiddle
UPD:如果要删除不匹配的标签或没有值的标签,可以使用多次修改。
对于这个样本数据
退货
| ID|瓦尔|重新命名|
| - -----|- -----|- -----|
| 1|123345<TAG_WITH_NO_VALUE/>|三百<NEW_TAG2>四十五</NEW_TAG2>|
| 2|小行星999|<NEW_TAG3>XXX</NEW_TAG3>|
fiddle
dzjeubhm2#
您可以通过生成XSLT来实现: