Download presentation
Presentation is loading. Please wait.
Published byFrancis Fields Modified over 8 years ago
1
Module 18 Querying XML Data in SQL Server® 2008 R2
2
Module Overview Using the T-SQL FOR XML Statement Getting Started with XQuery Shredding XML
3
Lesson 1: Using the T-SQL FOR XML Statement Introducing the FOR XML clause Using RAW Mode Queries Using Auto Mode Queries Using Explicit Mode Queries Using Path Mode Queries Retrieving Nested XML Demonstration 1A: FOR XML Queries
4
Introducing the FOR XML clause Extends SELECT syntax Returns XML instead of rows and columns Is configurable to return attributes, elements, and schema Benefits client applications that work with XML Converted to XML Client Application Database Server
5
SELECT c.CustomerID AS CustID, soh.SalesOrderID FROM Sales.Customer AS c INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID ORDER BY c.CustomerID FOR XML RAW; SELECT c.CustomerID AS CustID, soh.SalesOrderID FROM Sales.Customer AS c INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID ORDER BY c.CustomerID FOR XML RAW; SELECT c.CustomerID AS CustID, soh.SalesOrderID FROM Sales.Customer AS c INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID ORDER BY c.CustomerID FOR XML RAW, ELEMENTS; SELECT c.CustomerID AS CustID, soh.SalesOrderID FROM Sales.Customer AS c INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID ORDER BY c.CustomerID FOR XML RAW, ELEMENTS; SELECT c.CustomerID AS CustID, soh.SalesOrderID FROM Sales.Customer AS c INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID ORDER BY c.CustomerID FOR XML RAW('Order'), ROOT('Orders'); SELECT c.CustomerID AS CustID, soh.SalesOrderID FROM Sales.Customer AS c INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID ORDER BY c.CustomerID FOR XML RAW('Order'), ROOT('Orders'); Using RAW Mode Queries … … Is an XML representation of a rowset Contains either elements or attributes Has optional root element and row element name 11000 43793 … 11000 43793 … … …
6
Using Auto Mode Queries SELECT Customer.CustomerID AS CustID, Customer.StoreID, [Order].SalesOrderID FROM Sales.Customer AS Customer INNER JOIN Sales.SalesOrderHeader AS [Order] ON Customer.CustomerID = [Order].CustomerID ORDER BY Customer.CustomerID FOR XML AUTO; SELECT Customer.CustomerID AS CustID, Customer.StoreID, [Order].SalesOrderID FROM Sales.Customer AS Customer INNER JOIN Sales.SalesOrderHeader AS [Order] ON Customer.CustomerID = [Order].CustomerID ORDER BY Customer.CustomerID FOR XML AUTO;
7
SELECT 1 AS Tag, NULL AS Parent, SalesOrderID AS [Invoice!1!InvoiceNo], OrderDate AS [Invoice!1!Date!Element] FROM SalesOrderHeader FOR XML EXPLICIT SELECT 1 AS Tag, NULL AS Parent, SalesOrderID AS [Invoice!1!InvoiceNo], OrderDate AS [Invoice!1!Date!Element] FROM SalesOrderHeader FOR XML EXPLICIT 2001-07-01T00:00:00... 2001-07-01T00:00:00... Using Explicit Mode Queries SELECT 1 AS Tag, NULL AS Parent, SalesOrderID AS [Invoice!1!InvoiceNo], OrderDate AS [Invoice!1!Date!Element] FROM Sales.SalesOrderHeader FOR XML EXPLICIT; SELECT 1 AS Tag, NULL AS Parent, SalesOrderID AS [Invoice!1!InvoiceNo], OrderDate AS [Invoice!1!Date!Element] FROM Sales.SalesOrderHeader FOR XML EXPLICIT; 2005-07-01T00:00:00 2005-07-01T00:00:00 Allows tabular representation of XML documents TagParentInvoice!1!InvoiceNoInvoice!1!Date!Element 1NULL436592001-07-01T00:00:00 1NULL436602001-07-02T00:00:00 Attribute Element Allows complete control of XML format
8
Using Path Mode Queries SELECT p.BusinessEntityID "@EmpID", p.FirstName "EmpName/First", p.LastName "EmpName/Last" FROM Person.Person AS p FOR XML PATH SELECT p.BusinessEntityID "@EmpID", p.FirstName "EmpName/First", p.LastName "EmpName/Last" FROM Person.Person AS p FOR XML PATH Use XML Path Language (XPath) to specify XML format Allow creation of nested data and specify what should be exposed as an ELEMENT or an ATTRIBUTE Easier to use than EXPLICIT mode Min Su Min Su
9
17256 9 17256 9 11000 43793 5 51522 11000 43793 5 51522 SELECT Customer.CustomerID, Customer.TerritoryID, (SELECT SalesOrderID, [Status] FROM Sales.SalesOrderHeader AS soh WHERE Customer.CustomerID = soh.CustomerID FOR XML AUTO, TYPE) as Orders FROM Sales.Customer as Customer ORDER BY Customer.CustomerID FOR XML AUTO, ELEMENTS; SELECT Customer.CustomerID, Customer.TerritoryID, (SELECT SalesOrderID, [Status] FROM Sales.SalesOrderHeader AS soh WHERE Customer.CustomerID = soh.CustomerID FOR XML AUTO, TYPE) as Orders FROM Sales.Customer as Customer ORDER BY Customer.CustomerID FOR XML AUTO, ELEMENTS; SELECT Cust.CustomerID, Cust.StoreID, [Order].SalesOrderID, [Order].[Status] FROM Sales.Customer AS Cust INNER JOIN Sales.SalesOrderHeader AS [Order] ON Cust.CustomerID = [Order].CustomerID ORDER BY Cust.CustomerID FOR XML AUTO, ELEMENTS; SELECT Cust.CustomerID, Cust.StoreID, [Order].SalesOrderID, [Order].[Status] FROM Sales.Customer AS Cust INNER JOIN Sales.SalesOrderHeader AS [Order] ON Cust.CustomerID = [Order].CustomerID ORDER BY Cust.CustomerID FOR XML AUTO, ELEMENTS; SELECT Cust.CustomerID, Cust.StoreID, SalesOrderID, [Status] FROM Sales.Customer AS Cust INNER JOIN Sales.SalesOrderHeader AS [Order] ON Cust.CustomerID = [Order].CustomerID ORDER BY Cust.CustomerID FOR XML AUTO; SELECT Cust.CustomerID, Cust.StoreID, SalesOrderID, [Status] FROM Sales.Customer AS Cust INNER JOIN Sales.SalesOrderHeader AS [Order] ON Cust.CustomerID = [Order].CustomerID ORDER BY Cust.CustomerID FOR XML AUTO; AUTO mode produces only attributes or elements AUTO mode produces only attributes Retrieving Nested XML Use inner FOR XML with TYPE clause to return xml data type
10
Demonstration 1A: FOR XML Queries In this demonstration, you will see: How to retrieve XML in RAW mode How to retrieve XML in AUTO mode How to retrieve XML in EXPLICIT mode How to retrieve XML in PATH mode How to use TYPE
11
Lesson 2: Getting Started with XQuery What is XQuery? query() Method value() Method exist() Method modify() Method Demonstration 2A: XQuery Methods in a DDL Trigger
12
What is XQuery? Can query structured or semi-structured XML /InvoiceList/Invoice[@InvoiceNo=1000] FLWOR expressions StatementDescription forIterate through sibling nodes whereApply filtering criteria to the iteration order bySort values in returned resultset returnSpecify the XML to be returned Query language to identify nodes in XML
13
query() Method Returns untyped XML Uses an XQuery expression SELECT XmlEvent.query( ' { for $e in /EVENT_INSTANCE return {number($e/SPID[1])} } ') FROM dbo.DatabaseLog; SELECT XmlEvent.query( ' { for $e in /EVENT_INSTANCE return {number($e/SPID[1])} } ') FROM dbo.DatabaseLog;
14
value() Method Extracts scalar values from XML documents Returns data as a relational column SELECT CatalogDescription.value(' declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/a dventure-works/ProductModelDescription"; (/PD:ProductDescription/@ProductModelID)[1] ', 'int') as Result FROM Production.ProductModel WHERE CatalogDescription IS NOT NULL ORDER BY ProductModelID; SELECT CatalogDescription.value(' declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/a dventure-works/ProductModelDescription"; (/PD:ProductDescription/@ProductModelID)[1] ', 'int') as Result FROM Production.ProductModel WHERE CatalogDescription IS NOT NULL ORDER BY ProductModelID;
15
exist() Method Checks for the existence of a specific value Returns 1 when the value exists, 0 when it does not Should be used in preference to value() for better performance SELECT * FROM dbo.DatabaseLog WHERE XmlEvent.exist ('/EVENT_INSTANCE[ObjectType="TABLE"]') = 1; SELECT * FROM dbo.DatabaseLog WHERE XmlEvent.exist ('/EVENT_INSTANCE[ObjectType="TABLE"]') = 1;
16
SET @xmlCol.modify( 'replace value of (/InvoiceList/Invoice/SalesPerson/text())[1] with "Ted"'); SET @xmlCol.modify( 'replace value of (/InvoiceList/Invoice/SalesPerson/text())[1] with "Ted"'); SET @xmlDoc.modify( 'delete (/InvoiceList/Invoice/SalesPerson)[1]'); SET @xmlDoc.modify( 'delete (/InvoiceList/Invoice/SalesPerson)[1]'); modify() Method SET @xmlDoc.modify( 'insert element salesperson {"Bill"} as first into (/InvoiceList/Invoice)[1]'); SET @xmlDoc.modify( 'insert element salesperson {"Bill"} as first into (/InvoiceList/Invoice)[1]'); “insert” adds child nodes to an XML document “replace value of” updates node in an XML document “delete” removes a node from the XML document
17
Demonstration 2A: XQuery Methods in a DDL Trigger In this demonstration, you will see how to use XQuery in DDL triggers
18
Lesson 3: Shredding XML Overview of Shredding XML data Stored Procedures for Managing In-Memory Node Trees OPENXML Working with XML Namespaces nodes() Method Demonstration 3A: Shredding XML
19
Overview of Shredding XML data XML document received from client 1 1 Use OPENXML to retrieve rowset 3 3 Use sp_xml_removedocument to clean up memory tree 5 5 Create internal tree representation by using sp_xml_preparedocument Create internal tree representation by using sp_xml_preparedocument 2 2 Process (or shred) the data into tables 4 4
20
Stored Procedures for Managing In-Memory Node Trees CREATE PROCEDURE Sales.ProcessOrder @DocumentData xml AS -- Declare document handle DECLARE @Handle int; -- Create memory tree EXEC sp_xml_preparedocument @Handle OUTPUT, @DocumentData; -- Code for processing document goes here -- using OPENXML -- Remove memory tree EXEC sp_xml_removedocument @Handle; CREATE PROCEDURE Sales.ProcessOrder @DocumentData xml AS -- Declare document handle DECLARE @Handle int; -- Create memory tree EXEC sp_xml_preparedocument @Handle OUTPUT, @DocumentData; -- Code for processing document goes here -- using OPENXML -- Remove memory tree EXEC sp_xml_removedocument @Handle; Create tree by using sp_xml_preparedocument Free memory by using sp_xml_removedocument
21
OPENXML <Order SalesOrderID="43860" Status="5" OrderDate="2001-08-01T00:00:00"> <Order SalesOrderID="43860" Status="5" OrderDate="2001-08-01T00:00:00"> SELECT * FROM OPENXML (@idoc, '/Customer/Order/OrderDetail', 1) WITH (CustomerID int'../../@CustomerID', OrderID int'../@SalesOrderID', OrderDate datetime'../@OrderDate', ProdID int'@ProductID', Quantity int) SELECT * FROM OPENXML (@idoc, '/Customer/Order/OrderDetail', 1) WITH (CustomerID int'../../@CustomerID', OrderID int'../@SalesOrderID', OrderDate datetime'../@OrderDate', ProdID int'@ProductID', Quantity int) From Order element From Customer element Uses attributes as default rowpattern identifies node level Defaults to Quantity attribute From OrderDetail element ColPattern identifies SalesOrderID, Status, and OrderDate
22
Working with XML Namespaces <Customer xmlns="urn:AW_NS" xmlns:o="urn:AW_OrderNS" CustomerID="1" CustomerType="S"> <o:Order SalesOrderID="43860" Status="5" OrderDate="2001-08-01T00:00:00"> <Customer xmlns="urn:AW_NS" xmlns:o="urn:AW_OrderNS" CustomerID="1" CustomerType="S"> <o:Order SalesOrderID="43860" Status="5" OrderDate="2001-08-01T00:00:00"> sp_xml_preparedocument accepts namespaces Use namespace prefix in all XPath expressions EXEC sp_xml_preparedocument @idoc OUTPUT, @doc, '<ROOT xmlns:rootNS="urn:AW_NS" xmlns:orderNS="urn:AW_OrderNS"/>'; SELECT * FROM OPENXML (@idoc, '/rootNS:Customer/orderNS:Order/orderNS:OrderDetail')... EXEC sp_xml_preparedocument @idoc OUTPUT, @doc, '<ROOT xmlns:rootNS="urn:AW_NS" xmlns:orderNS="urn:AW_OrderNS"/>'; SELECT * FROM OPENXML (@idoc, '/rootNS:Customer/orderNS:Order/orderNS:OrderDetail')...
23
nodes() Method SELECT nCol.value('@ProductID', 'int') Product, nCol.value('@Quantity', 'int') Qty FROM @xmlOrder.nodes('/Order/LineItem') AS nTable(nCol) SELECT nCol.value('@ProductID', 'int') Product, nCol.value('@Quantity', 'int') Qty FROM @xmlOrder.nodes('/Order/LineItem') AS nTable(nCol) SELECT EventDetail.value('PostTime[1]','datetime2') AS PostTime, EventDetail.value('SPID[1]', 'int') AS SPID, EventDetail.value('ObjectType[1]','sysname') AS ObjectType, EventDetail.value('ObjectName[1]','sysname') AS ObjectName FROM dbo.DatabaseLog AS dl CROSS APPLY dl.XmlEvent.nodes('/EVENT_INSTANCE') AS EventInfo(EventDetail) ORDER BY PostTime; SELECT EventDetail.value('PostTime[1]','datetime2') AS PostTime, EventDetail.value('SPID[1]', 'int') AS SPID, EventDetail.value('ObjectType[1]','sysname') AS ObjectType, EventDetail.value('ObjectName[1]','sysname') AS ObjectName FROM dbo.DatabaseLog AS dl CROSS APPLY dl.XmlEvent.nodes('/EVENT_INSTANCE') AS EventInfo(EventDetail) ORDER BY PostTime; Shreds XML variables into relational data Requires the APPLY operator with XML columns
24
Demonstration 3A: Shredding XML In this demonstration, you will see how to shred XML data using the nodes() method
25
Lab 18: Querying XML Data in SQL Server Exercise 1: Learn to query SQL Server data as XML Exercise 2: Write a stored procedure returning XML Challenge Exercise 3: Write a stored procedure that updates using XML (Only if time permits) Logon information Estimated time: 45 minutes
26
Lab Scenario In this lab, you will investigate several ways in which XML data can be used in SQL Server. You will query relational data and return it as XML and also process existing XML data using T-SQL. If you have time, your manager has an additional task for you. A new web service is being added to the marketing system. You need to create a stored procedure that will query data from a table and return it as an XML value.
27
Lab Review XML data could be passed to a stored procedure using either the XML data type or the nvarchar data type. What advantage does the XML data type provide over the nvarchar data type for this purpose? Which XML query mode did you use for implementing the WebStock.GetAvailableModelsAsXML stored procedure?
28
Module Review and Takeaways Review Questions Best Practices
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.