Understanding PUL, seeing modified result
Monday, 17 August 2020 · 2 messages
BP
Ben Pracht17 Aug 2020 03:59 #
Hi,
I'm a bit more familiar with a SQL database like Oracle than BaseX, though I did cut my teeth on MarkLogic. MarkLogic from what I've read seems to handle updates differently than BaseX. I'm working through examples I found from the website, but wanted to adapt them for my own understanding.
I believe every time I have the copy keyword, it's creating a copy of variable and applies one or more modfiications to that copy. Because the original isn't changed, it's called "non-updating". For instance
copy $c := <peace/>
modify (
insert node element german { 'Friede'} into $c,
insert node attribute guid {'asdf'} into $c
)
return $cthe original node <peace/>, even if it were a variable would not be touched.
However,
insert node element german { 'Friede'} into <peace/>
Takes the <peace/> element, modifies it and returns the modified form. Or at least it does not complain. I ran SET
WRITEBACK on and set MIXEDUPDATES before starting these examples.
Unfortunately, the insert above just returns an empty set. I *think* it puts it into some PUL list, not unlike a set of transactions to be applied. These modifications seem to be invisible to subsequent queries, even in the same session (unlike a SQL database wherein the same session would see the modifications).
How can I get these changes flushed so I can see and use the modified result?
Separately, if I do haver an insert or some other modification, what's the syntax if I wanted to add a for, let order by or other FLOWR keyword?
Kind Regards,
Ben Pracht
919.809.2439
ben.pracht at gmail.comCG
Christian Grün17 Aug 2020 09:14 #
Hi Ben,
Quoted text · Ben Pracht · 1 line
> Unfortunately, the insert above just returns an empty set. I *think* it puts it into some PUL list, not unlike a set of transactions to be applied. These modifications seem to be invisible to subsequent queries, even in the same session (unlike a SQL database wherein the same session would see the modifications).
Well summarized; this is the way how the XQuery Update Facility works. As you have created the updated node inside the updating query, and as updating queries return no results, you won’t have any insight into the changes.
There are basically two solutions (depending on what you want to do):
1. In SQL, you usually update existing resources. If you want to do the same in XQuery, you need to address the resource in your quer, e.g. via
fn:doc or db:open:
insert node element german { 'Friede' } into doc('world.xml')/peace
2. If you want to create new nodes in your query and update and return those, you can use the “non-updating” expression: <peace/> update {
insert node element german { 'Friede' } into .
}Quoted text · Ben Pracht · 1 line
> Separately, if I do haver an insert or some other modification, what's the syntax if I wanted to add a for, let order by or other FLOWR keyword?
XQuery is “fully composable”, which means that FLWOR expressions can be used nearly anywhere. Just an example:
let $node := <peace/>
return $node update {
for $new in (<german>Friede</german>, <french>paix</french>)
order by name($new)
return insert node $new into .
}Hope this helps
Christian
Written for BaseX 9.4. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery