I have an xml structure that looks like this:
<data>
<a>
<element name="aName">123</element>
<element name="xyz">foobar</element>
</a>
<b>
<element name="aName">foo</element>
<element name="otherName">bar</element>
</b>
</data>
Which is saved in an XML column in a DB2 database. Within /a/element/@name is unique and /b/element/@name is unique etc.
Now I want to insert a new element tag in either ,. If an element with the same name attribute already exists, I want to replace that element (order of element tags do not matter). I did this like that:
update mytable set myXmlColumn=xmlquery('copy $new := $old modify
(
do delete $new/data/a/element[@name=$newName],
do insert $insert as last into $new/data/a
) return $new'
passing
'aName' as "newName",
xmlparse(document '<element name="aName">aaa</element>') as "insert"),
myXmlColumn as "old"
) where id=123
This inserts the new element all right, removing another element with the same name if it existed. But know I want this to work even if the tag does not exist yet (in this case an empty tag should be created and the new element should be added to it) and it should still work if myXmlColumn was previously null.
For the latter requirement I found a solution although it strikes me as rather inelegant: In the passing section I can write coalesce(myXmlColumn,xmlparse(document '<data><a /></data>')), which will make the statement work if myXmlColumn is null. But what if it is not null, but just the is missing?
I found a solution that works, although it still feels awkward. I wonder if there is a more elegant solution…