Upload
andra
View
70
Download
0
Embed Size (px)
DESCRIPTION
Module 3: Using XML. Overview. Retrieving XML by Using FOR XML Shredding XML by Using OPENXML Introducing XQuery Using the xml Data Type. Lesson 1: Retrieving XML by Using FOR XML. Introduction to the FOR XML Clause What Are RAW Mode Queries? What Are AUTO Mode Queries? - PowerPoint PPT Presentation
Citation preview
Module 3:Using XML
Overview
Retrieving XML by Using FOR XML
Shredding XML by Using OPENXML
Introducing XQuery
Using the xml Data Type
Lesson 1: Retrieving XML by Using FOR XML
Introduction to the FOR XML Clause
What Are RAW Mode Queries?
What Are AUTO Mode Queries?
What Are EXPLICIT Mode Queries?
What Are PATH Mode Queries?
Syntax for Retrieving Nested XML
Practice: Using FOR XML
Introduction to the FOR XML Clause
Extends SELECT syntax
Returns XML instead of rows and columns
Configurable to return attributes, elements, and schema
Benefits client applications that work with XML
Converted to XMLConverted to XML
Client ApplicationClient ApplicationDatabase ServerDatabase Server
<row CustID="1" CustomerType="S" SalesOrderID="43860"/><row CustID="1" CustomerType="S" SalesOrderID="44501"/>...
<row CustID="1" CustomerType="S" SalesOrderID="43860"/><row CustID="1" CustomerType="S" SalesOrderID="44501"/>...
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML RAW
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML RAW
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML RAW, ELEMENTS
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML RAW, ELEMENTS
<row><CustID>1</CustID><CustomerType>S</CustomerType><SalesOrderID>43860</SalesOrderID>
</row>...
<row><CustID>1</CustID><CustomerType>S</CustomerType><SalesOrderID>43860</SalesOrderID>
</row>...
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML RAW('Order'), ROOT('Orders')
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML RAW('Order'), ROOT('Orders')
<Orders><Order><CustID>1</CustID><CustomerType>S</...</Order>...
</Orders>
<Orders><Order><CustID>1</CustID><CustomerType>S</...</Order>...
</Orders>
What Are RAW Mode Queries?
XML representation of a rowsetXML representation of a rowset
Contains either elements or attributesContains either elements or attributes
Optional root element and row element nameOptional root element and row element name
What Are AUTO Mode Queries?
XML representation of data entities
Nest data based on join precedence
Can use options such as ELEMENTS and ROOT
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML AUTO
SELECT Cust.CustomerID CustID, CustomerType, SalesOrderIDFROM Customer Cust JOIN SalesOrderHeader [Order] ON Cust.CustomerID = [Order].CustomerIDORDER BY Cust.CustomerIDFOR XML AUTO
<Cust CustID="1" CustomerType="S"><Order SalesOrderID="43860" /><Order SalesOrderID="44501" />...
</Cust><Cust CustID="2" CustomerType="S">...
<Cust CustID="1" CustomerType="S"><Order SalesOrderID="43860" /><Order SalesOrderID="44501" />...
</Cust><Cust CustID="2" CustomerType="S">...
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
What Are EXPLICIT Mode Queries?
<Invoice InvoiceNo="43659"><Date>2001-07-01T00:00:00</Date>
</Invoice><Invoice InvoiceNo="43660">...
<Invoice InvoiceNo="43659"><Date>2001-07-01T00:00:00</Date>
</Invoice><Invoice InvoiceNo="43660">...
Tabular representations of XML documentsTabular representations of XML documents
Allow complete control of XML formatAllow complete control of XML format
ElementElement
AttributeAttribute
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
<Invoice InvoiceNo="43659"><Date>2001-07-01T00:00:00</Date>
</Invoice><Invoice InvoiceNo="43660">...
<Invoice InvoiceNo="43659"><Date>2001-07-01T00:00:00</Date>
</Invoice><Invoice InvoiceNo="43660">...
Tag Parent Invoice!1!InvoiceNo Invoice!1!Date!Element
1 NULL 43659 2001-07-01T00:00:00
1 NULL 43660 2001-07-02T00:00:00
What Are PATH Mode Queries?
Use XPath to specify XML format
Allow creation of nested data
Easier to use than EXPLICIT mode
SELECT EmployeeID "@EmpID", FirstName "EmpName/First", LastName "EmpName/Last"FROM Person.Contact INNER JOIN Employee
ON Person.Contact.ContactID = Employee.ContactIDFOR XML PATH
SELECT EmployeeID "@EmpID", FirstName "EmpName/First", LastName "EmpName/Last"FROM Person.Contact INNER JOIN Employee
ON Person.Contact.ContactID = Employee.ContactIDFOR XML PATH
<row EmpID="1"><EmpName>
<First>Guy</First><Last>Gilbert</Last>
</EmpName></row>...
<row EmpID="1"><EmpName>
<First>Guy</First><Last>Gilbert</Last>
</EmpName></row>...
Syntax for Retrieving Nested XML
AUTO mode produces only attributes or elementsAUTO mode produces only attributes or elements
Use inner FOR XML with TYPE clause to return xml data typeUse inner FOR XML with TYPE clause to return xml data type
Combine EXPLICIT mode with UNION ALLCombine EXPLICIT mode with UNION ALL
<Cust CustomerID="1" CustomerType="S"><Order SalesOrderID="43860" Status="5"/><Order SalesOrderID="44501" Status="5"/>...
</Cust>
<Cust CustomerID="1" CustomerType="S"><Order SalesOrderID="43860" Status="5"/><Order SalesOrderID="44501" Status="5"/>...
</Cust>
SELECT Cust.CustomerID, CustomerType, SalesOrderID, Status
FROM Customer Cust JOIN SalesOrderHeader [Order]ON Cust.CustomerID = [Order].CustomerID
ORDER BY Cust.CustomerIDFOR XML AUTO
SELECT Cust.CustomerID, CustomerType, SalesOrderID, Status
FROM Customer Cust JOIN SalesOrderHeader [Order]ON Cust.CustomerID = [Order].CustomerID
ORDER BY Cust.CustomerIDFOR XML AUTO
SELECT Cust.CustomerID, CustomerType, SalesOrderID, Status
FROM Customer Cust JOIN SalesOrderHeader [Order]ON Cust.CustomerID = [Order].CustomerID
ORDER BY Cust.CustomerIDFOR XML AUTO, ELEMENTS
SELECT Cust.CustomerID, CustomerType, SalesOrderID, Status
FROM Customer Cust JOIN SalesOrderHeader [Order]ON Cust.CustomerID = [Order].CustomerID
ORDER BY Cust.CustomerIDFOR XML AUTO, ELEMENTS
<Cust><CustomerID>1</CustomerID><CustomerType>S</CustomerType><Order>
<SalesOrderID>43860</SalesOrderID><Status>5</Status>...
<Cust><CustomerID>1</CustomerID><CustomerType>S</CustomerType><Order>
<SalesOrderID>43860</SalesOrderID><Status>5</Status>...
SELECT Name CategoryName,(SELECT Name SubCategoryNameFROM ProductSubCategory SubCategoryWHERE SubCategory.ProductCategoryID =
Category.ProductCategoryIDFOR XML AUTO, TYPE, ELEMENTS)
FROM ProductCategory CategoryFOR XML AUTO
SELECT Name CategoryName,(SELECT Name SubCategoryNameFROM ProductSubCategory SubCategoryWHERE SubCategory.ProductCategoryID =
Category.ProductCategoryIDFOR XML AUTO, TYPE, ELEMENTS)
FROM ProductCategory CategoryFOR XML AUTO
<Category CategoryName="Accessories"><SubCategory>
<SubCategoryName>Bike Racks</SubCategoryName></SubCategory>...
<Category CategoryName="Accessories"><SubCategory>
<SubCategoryName>Bike Racks</SubCategoryName></SubCategory>...
<Invoice InvoiceNo="43659"><Date>2001-07-01T00:00:00</Date><LineItem ProductID="709">Bike Socks, M</LineItem><LineItem ProductID="711">Helmet, Blue</LineItem>
</Invoice>...
<Invoice InvoiceNo="43659"><Date>2001-07-01T00:00:00</Date><LineItem ProductID="709">Bike Socks, M</LineItem><LineItem ProductID="711">Helmet, Blue</LineItem>
</Invoice>...
SELECT 1 AS Tag, NULL AS Parent, ...FROM SalesOrderHeaderUNION ALLSELECT 2 AS Tag, 1 AS Parent, ...FROM SalesOrderDetail OD JOIN ...FOR XML EXPLICIT
SELECT 1 AS Tag, NULL AS Parent, ...FROM SalesOrderHeaderUNION ALLSELECT 2 AS Tag, 1 AS Parent, ...FROM SalesOrderDetail OD JOIN ...FOR XML EXPLICIT
Practice: Using FOR XML
In this practice, you will:
Retrieve XML in RAW mode
Retrieve XML in AUTO mode
Retrieve XML in EXPLICIT mode
Retrieve XML in PATH mode
Lesson 2: Shredding XML by Using OPENXML
Overview of Shredding XML Data
Stored Procedures for Managing In-Memory Node Trees
OPENXML Syntax
Syntax for Working With XML Namespaces
Practice: Using OPENXML to Shred XML
XML documentreceived from clientXML documentreceived from client
11
Overview of Shredding XML Data
Use OPENXML to retrieve rowsetUse OPENXML to retrieve rowset
33
Use sp_xml_removedocumentto clean up memory treeUse sp_xml_removedocumentto clean up memory tree55
Create internal tree representation by using sp_xml_preparedocument
Create internal tree representation by using sp_xml_preparedocument
22
Process (or shred) the data into tablesProcess (or shred) the data into tables
44
Stored Procedures for Managing In-Memory Node Trees
Create tree by using sp_xml_preparedocument
Free memory by using sp_xml_removedocument
CREATE PROC ProcessOrder @doc xml -- xml data
AS
-- Declare document handleDECLARE @hdoc integer
-- Create memory treeEXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
-- Process Document
-- Remove memory treeEXEC sp_xml_removedocument @hdoc
CREATE PROC ProcessOrder @doc xml -- xml data
AS
-- Declare document handleDECLARE @hdoc integer
-- Create memory treeEXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
-- Process Document
-- Remove memory treeEXEC sp_xml_removedocument @hdoc
OPENXML Syntax
<Customer CustomerID="1" CustomerType="S"> <Order SalesOrderID="43860" Status="5" OrderDate="2001-08-01T00:00:00"> <OrderDetail ProductID="761" Quantity="2"/> <OrderDetail ProductID="770" Quantity="1"/> </Order></Customer>
<Customer CustomerID="1" CustomerType="S"> <Order SalesOrderID="43860" Status="5" OrderDate="2001-08-01T00:00:00"> <OrderDetail ProductID="761" Quantity="2"/> <OrderDetail ProductID="770" Quantity="1"/> </Order></Customer>
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 Order element
From Customer element
From Customer element
Uses attributes as defaultUses attributes as defaultrowpattern identifies node levelrowpattern identifies node level
Defaults to Quantity attributeDefaults to Quantity attribute From OrderDetail elementFrom OrderDetail element
Syntax for Working With XML Namespaces
sp_xml_preparedocument accepts namespaces
Use namespace prefix in all XPath expressions
<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"> <o:OrderDetail ProductID="761" Quantity="2"/> <o:OrderDetail ProductID="770" Quantity="1"/> </o:Order></Customer>
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')WITH...
<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"> <o:OrderDetail ProductID="761" Quantity="2"/> <o:OrderDetail ProductID="770" Quantity="1"/> </o:Order></Customer>
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')WITH...
Practice: Using OPENXML to Shred XML
In this practice, you will:
Use the OPENXML function
Shred XML by using elements only
Shred XML by using attributes or elements
Shred XML by using a colpattern parameter
Lesson 3: Introducing XQuery
What Is XQuery?
XQuery Basics
XQuery Expressions
What Is XQuery?
Query language to identify nodes in XMLQuery language to identify nodes in XML
/InvoiceList/Invoice[@InvoiceNo=1000]/InvoiceList/Invoice[@InvoiceNo=1000]
FLWOR statementsFLWOR statements
Statement Descriptionfor Iterate through sibling nodes
where Apply filtering criteria to the iteration
order by Sort values in returned resultset
return Specify the XML to be returned
Sequences and QNamesSequences and QNames
XQuery Basics
Result of an XQuery expression is a sequence
All identifiers are QNames
Result of an XQuery expression is a sequence
All identifiers are QNames
OperatorsOperators
Arithmetic comparison
General comparison
Value comparison
Node comparison
Node order comparison
Logical
Arithmetic comparison
General comparison
Value comparison
Node comparison
Node order comparison
Logical
CommentsComments
(: Comment text :) (: Comment text :)
if-then-elseif-then-else
if ( $A eq $B )then <result>A</result>else <result>B</result>
if ( $A eq $B )then <result>A</result>else <result>B</result>
Path expressionsPath expressions
XQuery Expressions
RelativeRelative
Primary expressionsPrimary expressions
Literals
Variable references
Function calls
Literals
Variable references
Function calls
Sequence expressionsSequence expressions
Construct, filter and combine sequencesConstruct, filter and combine sequences declare @x xml
set @x = '<root><abc></abc><abc attrAbc="1"></abc><abc attrAbc="2"></abc></root>'SELECT
@x.query('/root/abc[attrAbc]')
declare @x xmlset @x = '<root><abc></abc><abc attrAbc="1"></abc><abc attrAbc="2"></abc></root>'SELECT
@x.query('/root/abc[attrAbc]')
child::Address/child::Country child::Address/child::Country
AbsoluteAbsolute
/Address/Country /Address/Country
Lesson 4: Using the xml Data Type
What Is the xml Data Type?
The query, value, and exist Methods
The modify Method
The nodes Method
Practice: Using the xml Data Type
What Is the xml Data Type?
Native data type for XML
Internal storage structure for XML InfoSet
Use for tables, variables, or parameters
Exposes methods to query and modify XML
-- usage within table definitionCREATE TABLE NewTable( Col1 int primary key,
Col2 xml )
-- usage as local variabledeclare @data xml
-- usage as parameter to stored procedureCREATE PROCEDURE SaveData(@doc xml) AS ...
-- usage within table definitionCREATE TABLE NewTable( Col1 int primary key,
Col2 xml )
-- usage as local variabledeclare @data xml
-- usage as parameter to stored procedureCREATE PROCEDURE SaveData(@doc xml) AS ...
The query, value, and exist Methods
SELECT xmlCol.query( '<InvoiceNumbers> { for $i in /InvoiceList/Invoice return <InvoiceNo> {number($i/@InvoiceNo)} </InvoiceNo> } </InvoiceNumbers>')
SELECT xmlCol.query( '<InvoiceNumbers> { for $i in /InvoiceList/Invoice return <InvoiceNo> {number($i/@InvoiceNo)} </InvoiceNo> } </InvoiceNumbers>')
SELECT xmlCol.value('(/InvoiceList/Invoice/@InvoiceNo)[1]', 'int')
SELECT xmlCol.value('(/InvoiceList/Invoice/@InvoiceNo)[1]', 'int')
SELECT xmlCol.exist('/InvoiceList/Invoice[@InvoiceNo=1000]')
SELECT xmlCol.exist('/InvoiceList/Invoice[@InvoiceNo=1000]')
SELECT Invoices.query( '<Store> {sql:column("StoreName")} </Store>')
SELECT Invoices.query( '<Store> {sql:column("StoreName")} </Store>')
Use query to return untyped XMLUse query to return untyped XML
Use value to return a scalar valueUse value to return a scalar value
Bind relational columns and variablesBind relational columns and variables
Use exist to check for the existence of a specified valueUse exist to check for the existence of a specified value
The 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]')
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]')
insert adds child nodes or siblings to an XML documentinsert adds child nodes or siblings to an XML document
replace value of updates a node in the XML documentreplace value of updates a node in the XML document
delete removes a node from the XML documentdelete removes a node from the XML document
The nodes Method
SELECT nCol.value('@ProductID', 'int') Product,
nCol.value('@Quantity', 'int') QtyFROM @xmlOrder.nodes('/Order/LineItem')AS nTable(nCol)
SELECT nCol.value('@ProductID', 'int') Product,
nCol.value('@Quantity', 'int') QtyFROM @xmlOrder.nodes('/Order/LineItem')AS nTable(nCol)
SELECT nCol.value('../@OrderID[1]', 'int') ID, nCol.value('@ProductID[1]', 'int') ProdFROM Orders CROSS APPLY OrderDoc.nodes('/Order/LineItem') AS nTable(nCol)
SELECT nCol.value('../@OrderID[1]', 'int') ID, nCol.value('@ProductID[1]', 'int') ProdFROM Orders CROSS APPLY OrderDoc.nodes('/Order/LineItem') AS nTable(nCol)
Shreds xml variables into relational dataShreds xml variables into relational data
Requires the APPLY operator with xml columnsRequires the APPLY operator with xml columns
Practice: Using the xml Data Type
In this practice, you will:
Use the xml data type
Use the query, value, and exist methods
Bind relational columns
Use the modify method to insert, update, and delete XML
Use the nodes method
Lab: Working With XML
Exercise 1: Mapping Relational Data and XML
Exercise 2: Storing XML Natively in the Database
Exercise 3: Using XQuery With xml Methods