Continuing with XQuery, today’s post addresses the .modify() method against the xml data type; this method is used to update XML documents by applying one of three XML DML statements (insert, delete, or replace) via the use of a SQL SET statement. Again, the idea is hand off the work between the XML engine and the SQL engine. For example, given the following example:
DECLARE @X XML SET @x = '<root><id>1</id></root>' SET @x.modify('insert <splat>hello world </splat> into /root[1]') SELECT @x
the output of this SQL is the following XML:
<root> <id>1</id> <splat>hello world </splat> </root>
So what happened? We took a very simple XML document, and passed XML DML into the .modify() method which stated that we should:
- insert a new node “<splat>hello world </splat>” into the XML document
- into the first instance of the root node (/root[1]).
That’s it; welcome to the world of XML DML (Data Manipulation Language). The syntax pattern for insert is pretty simple; action (insert) followed by an XML expression (<splat>hello world </splat> followed by the location of a second XML expression (into /root[1]). With some minor variation in pattern, these elements hold true for the other two XML DDL statements (delete; replace value of):
action | XML expression (1) | XML expression (2) | Sample |
insert | node | {as first | as last} into | after | before XQuery |
SET @x.modify(‘insert <splat>hello world!</splat> |
delete | node | **not used** | SET @x.modify(‘delete /root/splat[1]’) |
replace value of | node/value | with value | SET @x.modify(‘replace value of (/root/id/text())[1] with "2"’) |
Of course, the variation in the pattern is what makes this set of commands a challenge to keep straight, so I’ll try to briefly explain the patterns in order of increasing complexity:
- the delete pattern requires that a node singleton be identified for deletion. The XML expression must evaluate to a node in the XML document that is being updated.
- the insert pattern identifies a node to be added either into, before, or after a specific location path. If an instance of that node already exists, you should specify as first or as last in order to place the new node in the correct sequence.
- the replace value of requires two XML expressions; the first must evaluate to an existing value (as either an attribute or a text() value of an element). The second must evaluate to a specific value; a later blog post will show how to use XQuery to dynamically set that value.
One more thing; these examples all use a single XML variable, and issue the SET command against it. If you’re dealing with a table of XML documents, you can use the SQL UPDATE command to SET the XML column using this XQuery method and XML DML like so:
DECLARE @T TABLE (x XML) INSERT INTO @T VALUES ('<id>1</id>'), ('<id>2</id>') UPDATE @T SET x.modify('insert <new>sample</new> into /id[1]') SELECT * FROM @T
will return a result set like so:
Summary
To sum up:
- the .modify() method may be used either against an XML variable or an XML column in a table by using the SET statement (alone or in an UPDATE command, respectively), and
- there are three basic patterns for XML DML that are passed to the .modify() method, and
- the syntax can be confusing but allows for a great deal of fine-grained manipulation of the XML document when needed.