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 />

508<br />

First, we need to alter the OrderID to have information on what element it belongs to:<br />

SELECT CustomerID,<br />

COUNT(*) AS ‘CustomerID/OrderCount’<br />

FROM Sales.SalesOrderHeader Orders<br />

WHERE CustomerID = 29890 OR CustomerID = 30067<br />

GROUP BY CustomerID<br />

FOR XML PATH;<br />

By adding the “/”, and then placing CustomerID before the slash, we are telling <strong>SQL</strong> <strong>Server</strong> that<br />

OrderCount is below CustomerID in a hierarchy. Now, there are many ways an XML hierarchy can be<br />

structured, so let’s see what <strong>SQL</strong> <strong>Server</strong> does with this:<br />

298908<br />

3006712<br />

Now, if you recall, we wanted to make OrderCount an attribute of CustomerID, so, while we have<br />

OrderCount below CustomerID in the hierarchy, it’s still not quite in the place we wanted it. To do that,<br />

we can combine / and @, but we need to fully define all the hierarchy. Now, since I suspect this is a bit<br />

confusing, let’s take it in two steps — first, the way we might be tempted to do it, but that will yield a<br />

similar error to the earlier example:<br />

SELECT CustomerID,<br />

COUNT(*) AS ‘CustomerID/@OrderCount’<br />

FROM Sales.SalesOrderHeader Orders<br />

WHERE CustomerID = 29890 OR CustomerID = 30067<br />

GROUP BY CustomerID<br />

FOR XML PATH;<br />

Error time:<br />

Msg 6852, Level 16, State 1, Line 1<br />

Attribute-centric column ‘CustomerID/@OrderCount’ must not come after a<br />

non-attribute-centric sibling in XML hierarchy in FOR XML PATH.<br />

To fix this, we need to understand a bit about how things are constructed when building the XML tags.<br />

The key is that the tags are essentially built in the order you list them. So, if you are wanting to add attributes<br />

to an element, you need to keep in mind that they are part of the element tag — that means you need<br />

to define any attributes before you define any other content of that element (sub elements or raw text).<br />

In our case, we are presenting the CustomerID as being raw text, but the OrderCount as being an attribute<br />

(OK, backwards of what would be likely in real life, but hang with me here). This means we are<br />

telling <strong>SQL</strong> <strong>Server</strong> things backwards. By the time it sees the OrderCount information it is already done<br />

with attributes for CustomerID and can’t go back.<br />

So, to fix things for us, we simply need to tell it about the attributes before we tell it about any more elements<br />

or raw text:<br />

SELECT COUNT(*) AS ‘CustomerID/@OrderCount’,<br />

CustomerID

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

Saved successfully!

Ooh no, something went wrong!