Published on

January 29, 2020

Querying XML Data Type Using XQuery in SQL Server

In SQL Server, XQuery is a powerful feature that allows users to query and extract data from XML documents. With XQuery, you can apply data filters or WHERE clauses on XML elements, insert, update, and delete XML nodes and node values in an XML column, and use XML data typed input parameters in stored procedures.

Let’s explore how to query XML data type using XQuery with some examples. We will use a sample table with XML data for better explanation.

Fetching Value from Target XML Node

To retrieve XML node values in a tabular format, we can use XQuery with the nodes() and value() functions. The nodes() function specifies the XPATH location of the XML node, and the value() function returns the XML node or attribute values based on the specified XPATH.

Here’s an example:

SELECT e.BusinessEntityID, e.NationalIDNumber, e.OrganizationNode, e.JobTitle,
       X.Y.value('(BankName)[1]', 'VARCHAR(20)') as BankName,
       X.Y.value('(AnnualRevenue)[1]', 'VARCHAR(20)') as AnnualRevenue,
       X.Y.value('(BusinessType)[1]', 'VARCHAR(256)') as BusinessType,
       X.Y.value('(Specialty)[1]', 'VARCHAR(128)') as Specialty
FROM HumanResources.Employee e
OUTER APPLY e.emp_xml.nodes('EmployeeDetails/StoreDetail/Store') as X(Y)

In the above query, we are retrieving values from the XML nodes and displaying them in a tabular format. The XPATH specifies the location of the XML nodes, and the value() function retrieves the values from those nodes.

Applying Filters on XML Nodes

We can also apply filters on XML nodes using XQuery. For example, we can retrieve rows from a table where employees are using “International Bank” as the bank name.

SELECT *
FROM (
    SELECT e.BusinessEntityID, e.NationalIDNumber, e.OrganizationNode, e.JobTitle,
           X.Y.value('(BankName)[1]', 'VARCHAR(20)') as BankName,
           X.Y.value('(AnnualRevenue)[1]', 'VARCHAR(20)') as AnnualRevenue,
           X.Y.value('(BusinessType)[1]', 'VARCHAR(256)') as BusinessType,
           X.Y.value('(Specialty)[1]', 'VARCHAR(128)') as Specialty
    FROM HumanResources.Employee e
    CROSS APPLY e.emp_xml.nodes('EmployeeDetails/StoreDetail/Store') as X(Y)
) T
WHERE BankName = 'International Bank'

In the above query, we are applying a filter on the XML node value in the WHERE clause. We use a subquery to retrieve all values from the XML node and then apply the filter on the result set.

Handling Namespaces in XQuery

If an XML document has namespaces, we can handle them in XQuery by specifying the namespace handle in the XPATH or using the * wildcard to ignore the namespace.

SELECT e.BusinessEntityID, e.NationalIDNumber, e.OrganizationNode, e.JobTitle,
       X.Y.value('(*:BankName)[1]', 'VARCHAR(20)') as BankName,
       X.Y.value('(*:AnnualRevenue)[1]', 'VARCHAR(20)') as AnnualRevenue,
       X.Y.value('(*:BusinessType)[1]', 'VARCHAR(256)') as BusinessType,
       X.Y.value('(*:Specialty)[1]', 'VARCHAR(128)') as Specialty
FROM HumanResources.Employee e
OUTER APPLY e.emp_xml.nodes('/*:EmployeeDetails/*:StoreDetail/*:Store') as X(Y)
WHERE X.Y.value('(AnnualRevenue)[1]', 'BIGINT') > 100000

In the above query, we are using the *: notation to handle namespaces in the XPATH. This allows us to retrieve values from XML nodes even if they have namespaces.

Using EXIST() with XQuery

The exist() function in XQuery returns a BIT value (0 or 1) indicating whether a value exists or not based on the specified XPATH. We can use this function to check if a specific XML element value exists.

SELECT e.BusinessEntityID, e.NationalIDNumber, e.OrganizationNode, e.JobTitle
FROM HumanResources.Employee e
WHERE e.emp_xml.exist('(/*:EmployeeDetails/*:StoreDetail/*:Store/*:Specialty[.="Mountain"])') = 1

In the above query, we are using the exist() function to check if any rows exist where the Specialty XML node value is “Mountain”. This function improves query performance when dealing with larger XML data.

Combining XQuery Functions

We can combine multiple XQuery functions like exist(), nodes(), value(), and query() in a single SQL query to achieve better performance and implement complex business logic.

SELECT e.BusinessEntityID, e.NationalIDNumber, e.OrganizationNode, e.JobTitle,
       X.Y.value('(*:BankName)[1]', 'VARCHAR(30)') as BankName,
       X.Y.value('(*:AnnualRevenue)[1]', 'VARCHAR(20)') as AnnualRevenue,
       X.Y.value('(*:BusinessType)[1]', 'VARCHAR(256)') as BusinessType,
       X.Y.value('(*:Specialty)[1]', 'VARCHAR(128)') as Specialty
FROM HumanResources.Employee e
CROSS APPLY e.emp_xml.nodes('/*:EmployeeDetails/*:StoreDetail/*:Store') as X(Y)
WHERE e.emp_xml.exist('(/*:EmployeeDetails/*:StoreDetail/*:Store/*:Specialty[.="Mountain"])') = 1

In the above query, we are combining multiple XQuery functions to retrieve values from XML nodes and apply a filter on the Specialty XML node value.

By using XQuery in SQL Server, you can efficiently query and manipulate XML data, extract specific information from XML nodes, and apply filters on XML elements. This powerful feature enhances the capabilities of SQL Server when working with XML data.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.