Get off to a fast start with DB2 9 pureXML, Part 4: Query DB2 XML data with XQuery

The IBM DB2® V9 for Linux®, UNIX®, and Windows®(R) features significant new support for storing, managing, and searching XML data, referred to as pureXML. This series helps you master these new XML features quickly through several step-by-step articles that explain how to accomplish fundamental tasks. In this article, Learn how to query data stored in XML columns using XQuery. [25 Mar 2010: Originally written in 2006, this article has been updated to include changes in DB2 versions 9.5 and 9.7.--Ed.]

Share:

Don Chamberlin, IBM Fellow, IBM

Don Chamberlin, an IBM Fellow at Almaden Research Center, is one of IBM's representatives in the W3C XML Query Working Group. He is also a co-author of the Quilt language proposal, which formed the basis for the XQuery design. Don is best known as co-inventor of the SQL database language and as author of two books on the DB2 database system. He holds a B.S. from Harvey Mudd College and a Ph.D. from Stanford University. He is also an ACM Fellow and a member of the National Academy of Engineering.



Cynthia M. Saracco, Senior Software Engineer, IBM

C. M. Saracco works at IBM's Silicon Valley Laboratory in the DB2 XML organization. She works on database management, XML, Web application development, and related topics.



25 March 2010 (First published 06 April 2006)

Also available in Russian Vietnamese Portuguese Spanish

You've probably heard the buzz about DB2's V9 -- IBM's first database management system to support both tabular (SQL-based) and hierarchical (XML-based) data structures. Previous articles in the series have summarized DB2's new XML features, described how to create database objects and populate them with XML data, and explained how to work with XML data using SQL and SQL/XML. This article continues to explore DB2 XML capabilities by focusing on its new support for XQuery.

DB2 treats XQuery as a first-class language, allowing users to write XQuery expressions directly rather than requiring that users embed or wrap XQueries in SQL statements. Furthermore, DB2's query engine processes XQueries natively, meaning that it parses, evaluates, and optimizes XQueries without ever translating them into SQL behind the scenes. Of course, if you choose to write bilingual queries that include both XQuery and SQL expressions, DB2 will process and optimize these queries, too.

As with SQL/XML in Part 3 of the series, this article explores several common query tasks and looks at how you can use XQuery to accomplish your goals. First, briefly consider how XQuery differs from SQL.

About XQuery

XQuery differs from SQL in a number of key respects, largely because the languages were designed to work with different data models that have different characteristics. XML documents contain hierarchies and possess an inherent order. Tabular data structures supported by SQL-based DBMSs are flat and set based. As such, rows are unordered.

The differences between these data models yield a number of fundamental differences in their respective query languages, including:

  • XQuery supports path expressions to enable programmers to navigate through XML's hierarchical structure, while plain SQL (without XML extensions) does not.
  • XQuery supports both typed and untyped data, while SQL data is always defined with a specific type.
  • XQuery lacks null values because XML documents omit missing or unknown data. SQL, of course, uses nulls to represent missing or unknown data values.
  • XQuery returns sequences of XML data, while SQL returns result sets of various SQL data types.

This is a subset of the fundamental differences between XQuery and SQL. It is beyond the scope of this introductory article to provide an exhaustive list, but an IBM Systems Journal article discusses language differences in more detail. This article focuses on some basic aspects of the XQuery language and how you can use it to query XML data in DB2 V9.


Sample database

The queries in this article access the sample tables created in Part 1 of this series. For a quick review, Listing 1 defines the sample items and clients tables.

Listing 1. Table definitions
create table items (
id 		int primary key not null, 
brandname 	varchar(30), 
itemname 	varchar(30), 
sku 		int, 
srp 		decimal(7,2), 
comments 	xml
)

create table clients(
id 		int primary key not null, 
name 		varchar(50), 
status 		varchar(10), 
contactinfo 	xml
)

Sample XML data included in the items.comments column is shown in Listing 2, while sample XML data included in the clients.contactinfo column is shown in Listing 3. Subsequent query examples will reference specific elements in one or both of these XML documents.

Listing 2. Sample XML document stored in Comments column of Items table
<Comments>
	<Comment>
		<CommentID>133</CommentID>
		<ProductID>3926</ProductID>
		<CustomerID>8877</CustomerID>
		<Message>Heels on shoes wear out too quickly.</Message>
		<ResponseRequested>No</ResponseRequested>
	</Comment>
	<Comment>
		<CommentID>514</CommentID>
		<ProductID>3926</ProductID>
		<CustomerID>3227</CustomerID>
		<Message>Where can I find a supplier in San Jose?</Message>
		<ResponseRequested>Yes</ResponseRequested>
	</Comment>
</Comments>
Listing 3. Sample XML document stored in Contactinfo column of the Clients table
<Client>
	<Address>
		<street>5401 Julio Ave.</street>
		<city>San Jose</city>
		<state>CA</state>
		<zip>95116</zip>
	</Address>
	<phone>
		<work>4084630000</work>
		<home>4081111111</home>
		<cell>4082222222</cell>
	</phone>
	<fax>4087776666</fax>
	<email>love2shop@yahoo.com</email>
</Client>

Query environment

All the queries in this article are designed to be issued interactively. You can do this through the DB2 command line processor or the DB2 Command Editor of the DB2 Control Center. The screen images and instructions in this article focus on the latter. (IBM Data Studio and IBM Optim Development Studio ship with an Eclipse-based Developer Workbench that can help programmers graphically construct queries as well. This article does not discuss application development issues or the Development Studio.)

To use the DB2 Command Editor, launch the Control Center, and select Tools > Command Editor. A window similar to Figure 1 appears.

Figure 1. The DB2 Command Editor, which can be launched from the DB2 Control Center
Shows an SQL query in the top pane, and a record of commands entered in bottom pane

Type your queries in the upper pane, click on the green arrow in the upper left corner to run them, and view your output in the lower pane or in the separate Query Results tab.


XQuery examples

Just as in Part 3 of the series, this article steps through several common business scenarios and shows how to use XQuery to satisfy requests for XML data. It also explores more complex situations that involve embedding SQL within XQuery.

XQuery provides several different kinds of expressions that can be combined in any way you like. Each expression returns a list of values that can be used as input to other expressions. The result of the outermost expression is the result of the query.

This article focuses on two important kinds of XQuery expressions: FLWOR expressions and path expressions. A FLWOR expression is much like a SELECT-FROM-WHERE expression in SQL: it is used to iterate through a list of items and to optionally return something that is computed from each item. A path expression, on the other hand, navigates through a hierarchy of XML elements and returns the elements that are found at the end of the path.

Like a SELECT-FROM-WHERE expression in SQL, an XQuery FLWOR expression can contain several clauses that begin with certain keywords. The following keywords are used to begin clauses in a FLWOR expression:

  • for: Iterates through an input sequence, binding a variable to each input item in turn
  • let: Declares a variable and assigns it a value, which can be a list containing multiple items
  • where: Specifies criteria for filtering query results
  • order by: Specifies the sort order of the result
  • return: Defines the result to be returned

A path expression in XQuery consists of a series of steps, separated by slash characters. In its simplest form, each step navigates downward in an XML hierarchy to find the children of the elements returned by the previous step. Each step in a path expression can also contain a predicate that filters the elements that are returned by that step, retaining only elements that satisfy some condition. For example, assuming that the variable $clients is bound to a list of XML documents containing <Client> elements, the four-step path expression $clients/Client/Address[state = "CA"]/zip will return the list of zip codes for clients whose addresses are in California.

In many cases, it is possible to write a query by using either a FLWOR expression or a path expression.

Using DB2 XQuery as a top-level query language

To execute an XQuery directly in DB2 V9 (as opposed to embedding it in an SQL statement), you must preface the query with the keyword xquery. This instructs DB2 to invoke its XQuery parser to process your request. Note that you only need to do this if you are using XQuery as the outermost (or top level) language. If you embed XQuery expressions in SQL, you don't need to preface them with the xquery keyword. However, this article uses XQuery as the primary language, so all the queries are prefaced with xquery.

When running as a top-level language, XQuery needs to have a source of input data. One way in which an XQuery can obtain input data is to call a function named db2-fn:xmlcolumn with a parameter that identifies the table name and column name of an XML column in a DB2 table. The db2-fn:xmlcolumn function returns the sequence of XML documents that is stored in the given column. For example, the following query in Listing 4 returns a sequence of XML documents containing customer contact information.

Listing 4. Simple XQuery to return customer contact data
xquery db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')

As you might recall from our database schema (see "Sample database" section), XML documents are stored in the Contactinfo column of the Clients table. Note that the column and table names are specified in uppercase here. This is because table and column names are typically folded into uppercase before being written to DB2's internal catalog. Because XQuery is case-sensitive, lowercase table and column names would fail to match upper-case names in the DB2 catalog.

Retrieving specific XML elements

Now, explore a basic task. Suppose you want to retrieve the fax numbers of all clients who have provided you with this information. Listing 5 shows one way you can write this query.

Listing 5. FLWOR expression to retrieve client fax data
xquery 
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax
return $y

The first line instructs DB2 to invoke its XQuery parser. The next line instructs DB2 to iterate through the fax sub-elements of the Client elements contained in the CLIENTS.CONTACTINFO column. Each fax element is bound in turn to the variable $y. The third line indicates that, for each iteration, the value of $y is returned. The result is a sequence of XML elements, as shown Listing 6.

Listing 6. Sample output for previous query
<fax>4081112222</fax>
<fax>5559998888</fax>

As an aside, the output will also contain some information that's not of great interest in this article: XML version and encoding data, such as <?xml version="1.0" encoding="windows-1252" ?>, and XML namespace information, such as <fax xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">. To make the output easier for you to follow, that information is omitted from this article. However, it can be important for a number of XML applications. If you use the DB2 command line processor to run your queries, you can use the -d option to suppress the XML declaration information and the -i option to print the results in an attractive manner.

The query shown in Listing 5 could be expressed somewhat more concisely as a three-step path expression, as shown in Listing 7.

Listing 7. Path expression to retrieve client fax data
xquery 
db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax

The first step of the path expression calls the db2-fn:xmlcolumn function to obtain a list of XML documents from the CONTACTINFO column of the CLIENTS table. The second step returns all the Client elements in these documents, and the third step returns the fax elements nested inside these Client elements.

If you're not interested in obtaining XML fragments from your query but instead want just a text representation of qualifying XML element values, you can invoke the text() function in your return clause, as shown in Listing 8.

Listing 8. Two queries to retrieve text representation of client fax data
xquery 
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax
return $y/text()

(or)

xquery
db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax/text()

The output of these queries will be similar to that shown in Listing 9.

Listing 9. Sample output from previous queries
4081112222
5559998888

The results of the sample queries are relatively simple because the fax element is based on a primitive data type. Of course, elements can be based on complex types, which means they might contain sub-elements (or nested hierarchies). The Address element of our client contact information is one example of this. According to the schema defined in Part 2 of this series, it can contain a street address, apartment number, city, state, and zip code. Consider what the XQuery in Listing 10 would return.

Listing 10. FLWOR expression to retrieve complex XML type
xquery 
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
return $y

If you guessed a sequence of XML fragments containing Address elements and all their sub-elements, you're right. Listing 11 shows an example:

Listing 11. Sample output from previous query
<Address>
  <street>5401 Julio Ave.</street>
  <city>San Jose</city>
  <state>CA</state>
  <zip>95116</zip>
</Address>
. . . 
<Address>
  <street>1204 Meridian Ave.</street>
  <apt>4A</apt>
  <city>San Jose</city>
  <state>CA</state>
  <zip>95124</zip>
</Address>

Note: This sample output is formatted to make it easier for you to read. The DB2 Command Editor displays each customer address record on one line.

Filtering on XML element values

You can refine the previous XQuery examples to be more selective. For example, consider how to return the mailing addresses of all customers who live in U.S. zip code 95116.

As you might imagine, the XQuery where clause enables you to filter results based on the value of the zip element in your XML documents. Listing 12 shows how to add a where clause to the previous FLWOR expression in Listing 10 to obtain only the addresses that interest you.

Listing 12. FLWOR expression with a new "where" clause
xquery 
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
where $y/zip="95116"
return $y

The added where clause is pretty easy to understand. The for clause binds the variable $y to each address in turn. The where clause contains a small path expression that navigates from each address to its nested zip element. The where clause is true (and the address is retained) only if the value of this zip element is equal to 95116.

The same result could be obtained by adding a predicate to the path expression, as shown in Listing 13.

Listing 13. Path expression with additional filtering predicate
xquery
db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address[zip="95116"]

Of course, you can filter on zip code values and return elements unrelated to street addresses. Furthermore, you can also filter on multiple XML element values in a single query. The query in Listing 14 returns e-mail information for customers who live in a specific zip code in New York City (10011) or anywhere in the city of San Jose.

Listing 14. Filtering on multiple XML element values with a FLWOR expression
xquery 
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
where $y/Address/zip="10011" or $y/Address/city="San Jose"
return $y/email

Note that the for clause is changed so that it binds variable $y to Client elements rather than to Address elements. This enables you to filter the Client elements by one part of the subtree (Address) and return another part of the subtree (email). The path expressions in the where clause and return clause must be written relative to the element that is bound to the variable (in this case, $y).

The same query can be expressed somewhat more concisely as a path expression, as shown in Listing 15.

Listing 15. Filtering on multiple XML element values with a path expression
xquery 
db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client[Address/zip="10011"  
or Address/city="San Jose"]/email;

What's not as obvious from reviewing either form of this query is that the returned results will differ in two significant ways from what a SQL programmer might expect:

  1. You won't get XML data returned for qualifying customers who didn't give you their e-mail addresses. In other words, if you have 1000 customers who live in San Jose or zip code 10011, and 700 customers each gave you one e-mail address, you'd get a list of these 700 e-mail addresses returned. This is due to a fundamental difference between XQuery and SQL mentioned earlier: XQuery doesn't use nulls.
  2. You won't know which e-mail addresses were derived from the same XML document. In other words, if you have 700 customers who live in San Jose or zip code 10011, and each gave you two e-mail addresses, you'd get a list of 1400 email elements returned. You would not get a sequence 700 records, each consisting of two e-mail addresses.

Both situations can be desirable under some circumstances and undesirable under others. For example, if you need to e-mail a notice to every qualifying account you have on record, then iterating through a list of customer e-mail addresses in XML format is easy to do in an application. However, if you want to e-mail only one notice to every customer, including those who only provided you with their street addresses, then the XQuery previously shown won't be sufficient.

There are multiple ways you can rewrite this query so that the returned results represent missing information in some fashion and indicate when multiple e-mail addresses were derived from the same customer record, that is, the same XML document (more on this later). However, if all you want to do is retrieve a list containing one e-mail address per qualifying customer, you could modify the return clause of the previous query slightly.

Listing 16. Retrieving only the first email element per customer
xquery 
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
where $y/Address/zip="10011" or $y/Address/city="San Jose"
return $y/email[1]

This query causes DB2 to return the first e-mail element it finds within each qualifying XML document (customer contact record). If it doesn't find an e-mail address for a qualifying customer, it won't return anything for that customer.

Transforming XML output

A powerful aspect of XQuery is its ability to transform XML output from one form of XML into another. For example, you can use XQuery to retrieve all or part of your stored XML documents and convert the output into HTML for easy display in a Web browser. The query in Listing 17 retrieves the addresses of the clients, sorts the results by zip code, and converts the output into XML elements that are part of an unordered HTML list.

Listing 17. Querying DB2 XML data and returning results as HTML
xquery 
<ul> {
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
order by $y/zip
return <li>{$y}</li> 
} </ul>

The query can be dissected this way:

  • The query begins simply enough with the xquery keyword to indicate to the DB2 parser that XQuery is being used as the primary language.
  • The second line causes the HTML markup for an unordered list (<ul>) to be included in the results. It also introduces a curly bracket, the first of two sets used in this query. Curly brackets instruct DB2 to evaluate and process the enclosed expression rather than treat it as a literal string.
  • The third line iterates over client addresses, binding the variable $y to each address element in turn.
  • The fourth line includes a new order by clause, specifying that results must be returned in ascending order (the default order) based on customer zip codes (the zip sub-element of each address bound to $y).
  • The return clause indicates that the Address elements are to be surrounded by HTML list item tags before return.
  • The final line concludes the query and completes the HTML unordered list tag.

The output appears similar to that in Listing 18.

Listing 18. Sample HTML output of previous query
<ul>
  <li>
     <Address>
         <street>9407 Los Gatos Blvd.</street>
         <city>Los Gatos</city>
         <state>CA</state>
         <zip>95032</zip>
     </Address>
  </li>
  <li>
     <Address>
         <street>4209 El Camino Real</street>
         <city>Mountain View</city>
         <state>CA</state>
        <zip>95033</zip>
     </Address>
  </li>
. . . 
</ul>

Now consider a topic raised earlier: how to write an XQuery that will indicate missing values in the returned results as well as indicate when a single XML document (such as a single customer record) contains repeating elements (such as multiple email addresses). One way to do so involves wrapping the returned output in a new XML element, as shown in the query in Listing 19:

Listing 19. Indicating missing values and repeating elements in an XQuery result
xquery 
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
where $y/Address[zip="10011"] or $y/Address[city="San Jose"]
return <emailList> {$y/email} </emailList>

Running this query causes a sequence of emailList elements to be returned, one per qualifying customer record. Each emailList element contains e-mail data. If DB2 finds a single e-mail address in a customer's record, it returns that element and its value. If it finds multiple e-mail addresses, it returns all e-mail elements and their values. Finally, if it finds no e-mail address, it will return an empty emailList element. Thus, the output might appear as shown in Listing 20.

Listing 20. Sample output of previous query
<emailList>
   <email>love2shop@yahoo.com</email>
</emailList>
<emailList/>
<emailList>
   <email>beatlesfan36@hotmail.com</email>
   <email>lennonfan36@hotmail.com</email>
</emailList>       
. . .

Using conditional logic

XQuery's ability to transform XML output can be combined with its built-in support for conditional logic to reduce the complexity of application code. Consider a simple example. The Items table includes an XML column containing comments customers have made about products. For customers who have requested a response to their comments, you might want to create new Action elements containing the product ID, customer ID, and message so you can route this information to the appropriate person for handling. However, comments that don't require a response are still important to the business, and you don't want to just ignore them. Instead, create an Info element with just the product ID and message. Here's how you can use an XQuery if-then-else expression to accomplish this task:

Listing 21. Using an "if-then-else" expression in an XQuery
xquery 
for $y in db2-fn:xmlcolumn('ITEMS.COMMENTS')/Comments/Comment 
return ( 
	if ($y/ResponseRequested = 'Yes') 
		then <action>
			{$y/ProductID, 
			 $y/CustomerID, 
			 $y/Message}
		      </action>
		else ( <info>
			{$y/ProductID, 
			 $y/Message}
			</info>
		)
)

Most aspects of this query should be familiar to you by now, so concentrate on the conditional logic. The if clause determines whether the value of the ResponseRequested sub-element for a given comment is equal to Yes. If so, the then clause is evaluated, causing DB2 to return a new element (action) that contains three sub-elements: ProductID, CustomerID, and Message. Otherwise, the else clause is evaluated, and DB2 returns an Info element containing only product ID and message data.

Using the let clause

You have now seen how to use all the parts of a FLWOR expression except for the let clause. This clause is used to assign a value (possibly containing a list of several items) to a variable that can be used in other clauses of the FLWOR expression.

Suppose you want to make a list of how many comments were received for each product. This can be done with the query in Listing 22.

Listing 22. Using the "let" clause
xquery
for $p in distinct-values
     (db2-fn:xmlcolumn('ITEMS.COMMENTS')/Comments/Comment/ProductID)
let $pc := db2-fn:xmlcolumn('ITEMS.COMMENTS')
        /Comments/Comment[ProductID = $p]
return
   <product>
          <id> { $p } </id> 
          <comments> { count($pc) } </comments>
   </product>

The distinct-values function in the for clause returns a list of all the distinct values of ProductID that are found inside comments in the Comments column of the Items table. The for clause binds variable $p to each of these ProductID values in turn. For each value of $p, the let clause scans the Items column again and binds the variable $pc to a list containing all the comments whose ProductID matches the ProductID in $p. The return clause constructs a new product element for each distinct ProductID value. Each of these product elements contains two sub-elements: an id element containing the ProductID value and a comments element containing a count of how many comments were received for the given product.

The result of this example query might look something similar to Listing 23.

Listing 23. Sample output for the previous query
<product>
     <id>3926</id>
     <comments>28</comments>
</product>
<product>
      <id>4097</id>
      <comments>13</comments>
</product>

XQueries with embedded SQL

By now, you've seen how to write XQueries that retrieve XML document fragments, create new forms of XML output, and return different output based on conditions specified in queries themselves. In short, you've learned a few ways to use XQuery to query XML data stored in DB2.

To be sure, there's more to learn about XQuery than this brief article covers. But there is one more broad topic not covered yet: how to embed SQL within XQuery. Doing so can be useful if you need to write queries that filter data based on XML and non-XML column values.

You might recall from Part 3 of this series how to embed simple XQuery expressions within an SQL statement to accomplish this task. Here, look at how to do the opposite: embed SQL within XQuery to restrict results based on both traditional SQL data values and specific XML element values.

In place of the db2-fn:xmlcolumn function, which returns all the XML data in a column of a table, you can call the db2-fn:sqlquery function, which executes an SQL query and returns only the selected data. The SQL query passed to db2-fn:sqlquery must return XML data. This XML data can then be further processed by XQuery.

The query in Listing 24 retrieves information about comments involving products with a suggested retail price (srp) of more than $100 USD that include a customer request for a response. Recall that pricing data is stored in an SQL decimal column, while customer comments are stored as XML. The returned data, including the product ID, customer ID, and customer message, are included in a single XML action element for each qualifying comment stored in the database.

Listing 24. Embedding SQL within an XQuery
xquery 
for $y in 
db2-fn:sqlquery('select comments from items where srp > 100')/Comments/Comment 
where $y/ResponseRequested="Yes"
return (
   <action>
          {$y/ProductID, 
           $y/CustomerID, 
           $y/Message}
  </action>
)

Most of this query should look familiar to you by now, so take a look at the new function: db2-fn:sqlquery. DB2 processes the SQL SELECT statement supplied to this function to determine which rows contain information about items priced at more than $100 USD. The documents stored in these rows serve as inputs to a path expression that returns all the nested Comment elements. Subsequent portions of the query use the XQuery where clause to filter returned data further and to transform portions of the selected comments into new XML fragments.

With this in mind, consider how you might solve a slightly different problem. Imagine that you want a list of all e-mail addresses for Gold clients who live in San Jose. Furthermore, if you have multiple e-mail addresses for a single client, you want all of them to be included in the output as part of a single client record. Finally, if a qualifying Gold client didn't give you an e-mail address, you want to retrieve his or her mailing address. Listing 25 shows one way to write such a query:

Listing 25. Embedding SQL within an XQuery that includes conditional logic
xquery 
for $y in 
db2-fn:sqlquery('select contactinfo from clients where status=''Gold'' ')/Client
where $y/Address/city="San Jose"
return (
     if ($y/email) then <emailList>{$y/email}</emailList>
     else $y/Address   
)

Two aspects of this query deserve some explanation. First, the SELECT statement embedded in the second line contains a query predicate based on the Status column, comparing the value of this VARCHAR column to the string Gold. In SQL, such strings are surrounded by single quotes. Note that although the example might appear to use double quotes, it actually uses two single quotes before and after the comparison value (''Gold''). The extra single quotes are escape characters. If you use double quotes around your string-based query predicate, instead of pairs of single quotes, you'll get a syntax error.

In addition, the return clause in this query contains conditional logic to determine if an e-mail element is present in a given customer's record. If so, the query returns a new emailList element containing all the customer's e-mail addresses (that is, all the e-mail elements for that customer). If not, it returns the customer's mailing address (that is, the Address element for that customer).

Indexing

It's worth noting that you can create specialized XML indexes to speed access to data stored in XML columns. Because this is an introductory article and the sample data is small, the topic is not covered here. However, in production environments, defining appropriate indexes can be critical to achieving optimal performance. See Resources for more info about DB2's indexing technology.


Summary

XQuery differs from SQL in significant ways, several of which are highlighted in this article. Learning more about the language helps you determine when it can be most beneficial to your work, as well as help you understand when it can be useful to combine XQuery with SQL. Other articles in this series describe how to develop Java applications that exploit DB2 XML capabilities. For now though, this article includes a simple Java example, which depicts how a Java application might embed an XQuery.

Acknowledgments

Thanks to George Lapis, Matthias Nicola, and Gary Robinson for reviewing this article.

Resources

Learn

Get products and technologies

  • Build your next development project with IBM trial software, available for download directly from developerWorks.
  • Now you can use DB2 for free. Download DB2 Express-C, a no-charge version of DB2 Express Edition for the community that offers the same core data features as DB2 Express Edition and provides a solid base to build and deploy applications.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Information management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management, XML
ArticleID=107437
ArticleTitle=Get off to a fast start with DB2 9 pureXML, Part 4: Query DB2 XML data with XQuery
publish-date=03252010