17.06.2013 Views

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 16: A Brief XML Primer<br />

496<br />

between .nodes and a typical table is that we must cross apply our .nodes results back to the specific<br />

table that we are sourcing our XML data from. So, .nodes really involves more syntax than just<br />

“.nodes” — think of it somewhat like a join, but using the special CROSS APPLY keyword in the place<br />

of the JOIN and .nodes instead of the ON clause. It looks like this:<br />

SELECT <br />

FROM <br />

CROSS APPLY .nodes() AS <br />

This is fairly confusing stuff, so let’s look back at our .value example earlier. We see a query that looked<br />

for a specific entry and, therefore, got back exactly one result:<br />

WITH XMLNAMESPACES<br />

(‘http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuIn<br />

structions’ AS PI)<br />

SELECT ProductModelID,<br />

Instructions.value(‘(/PI:root/PI:Location/@LaborHours)[1]’,<br />

‘decimal (5,2)’) AS Location<br />

FROM Production.ProductModel<br />

WHERE ProductModelID = 66;<br />

Note that the URL portion of the namespace declaration must be entered on a single line. They are<br />

shown here word wrapped onto multiple lines because there is a limit to the number of characters we<br />

can show per line in print. Make sure you include the entire URL on a single line.<br />

.value expects a scalar result, so we needed to make certain our XQuery would return just that single<br />

value per individual row of XML. .nodes tells <strong>SQL</strong> <strong>Server</strong> to use XQuery to map to a specific location<br />

and treat each entry found in that XQuery as an individual row instead of a discrete value.<br />

WITH XMLNAMESPACES<br />

(‘http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/<br />

ProductModelManuInstructions’ AS PI)<br />

SELECT pm.ProductModelID,<br />

pmi.Location.value(‘./@LocationID’, ‘int’) AS LocationID,<br />

pmi.Location.value(‘./@LaborHours’, ‘decimal(5,2)’) AS LaborHours<br />

FROM Production.ProductModel pm<br />

CROSS APPLY pm.Instructions.nodes(‘/PI:root/PI:Location’) AS pmi(Location);<br />

Note that the URL portion of the namespace declaration must be entered on a single line. They are<br />

shown here word wrapped onto multiple lines because there is a limit to the number of characters we<br />

can show per line in print. Make sure you include the entire URL on a single line.<br />

Notice that through the use of our .nodes method, we are essentially turning one table (ProductModel)<br />

into two tables (the source table and the .nodes results from the Instructions column within the<br />

ProductModel table). Take a look at the results:<br />

ProductModelID LocationID LaborHours<br />

-------------- ----------- ---------------------------------------<br />

7 10 2.50<br />

7 20 1.75

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!