The FOR XML clause is valid only in the SELECT statement and is subject to these limitations:
Example A
SELECT *
FROM Table1
WHERE ......(SELECT * FROM Table2 FOR XML RAW)
Example B
DECLARE @doc nchar(3000)
SET @doc = (SELECT * FROM Customers WHERE CustomerID = 'ALFKI' FOR XML RAW)
SELECT OrderID, UnitPrice
FROM [Order Details]
ORDER BY OrderID COMPUTE SUM(UnitPrice) BY OrderID
SELECT max(price), min(price), avg(price)
FROM titles
FOR XML AUTO
CREATE VIEW AllOrders AS SELECT * FROM Orders FOR XML AUTO
However, a statement such as the following is allowed:
SELECT * FROM ViewName FOR XML AUTO are allowed.
For example, consider this query:
SELECT TOP 1 LastName
FROM ServerName.Northwind.dbo.Employees
FOR XML AUTO
When ServerName is a local server, the query returns:
<Northwind.dbo.Employees LastName="Buchanan"/>
When ServerName is a network server, the query returns:
<ServerName.Northwind.dbo.Employees LastName="Buchanan"/>
This can be avoided by specifying this alias:
SELECT TOP 1 LastName
FROM ServerName.Northwind.dbo.Employees x
FOR XML AUTO
This query returns:
<x ="Buchanan"/>
The FOR BROWSE mode is implemented when a query with the FOR XML AUTO mode is specified. The FOR XML AUTO mode uses the information provided by the FOR BROWSE mode in determining the hierarchy in the result set.
For example, consider the following query. A derived table P is created in the query.
SELECT c.CompanyName,
o.OrderID,
o.OrderDate,
p.ProductName,
p.Quantity,
p.UnitPrice,
p.Total
FROM Customers AS c
JOIN
Orders AS o
ON
c.CustomerID = o.CustomerID
JOIN
(
SELECT od.OrderID,
pr.ProductName,
od.Quantity,
od.UnitPrice,
od.Quantity * od.UnitPrice AS total
FROM Products AS pr
JOIN
[Order Details] AS od
ON
pr.ProductID = od.ProductID
) AS p
ON
o.OrderID = p.OrderID
FOR XML AUTO
This is the partial result:
<c CompanyName="Vins et alcools Chevalier">
<o OrderID="10248" OrderDate="1996-07-04T00:00:00">
<pr ProductName="Queso Cabrales">
<od Quantity="12" UnitPrice="14.0000" total="168.0000"/>
</pr>
<pr ProductName="Singaporean Hokkien Fried Mee">
<od Quantity="10" UnitPrice="9.8000" total="98.0000"/>
</pr>
</c>
In the resulting XML document, the <p> element is missing, and the <pr> and <od> elements are returned. This occurs because the query optimizer eliminates the P table in the result and returns a result set consisting of the od and pr tables.
This can be avoided by rewriting the query. For example, you can rewrite the query is to create a view and use it in the SELECT statement:
CREATE VIEW p AS
SELECT od.OrderID,
pr.ProductName,
od.Quantity,
od.UnitPrice,
od.Quantity * od.UnitPrice AS total
FROM Products AS pr
JOIN
[Order Details] AS od
ON
pr.ProductID = od.ProductID
And then write the SELECT statement:
SELECT c.CompanyName,
o.OrderID,
o.OrderDate,
p.ProductName,
p.Quantity,
p.UnitPrice,
p.total
FROM Customers AS c
JOIN
Orders AS o
ON
c.CustomerID = o.CustomerID
JOIN
p
ON
o.OrderID = p.OrderID
FOR XML AUTO
This is the partial result:
<c CompanyName="Vins et alcools Chevalier">
<o OrderID="10248" OrderDate="1996-07-04T00:00:00">
<p ProductName="Queso Cabrales"
Quantity="12"
UnitPrice="14.0000"
total="168.0000"/>
</o>
</c>
In addition, SQL Server names containing characters that are invalid in XML names (such as spaces) are translated into XML names in a way in which the invalid characters are translated into escaped numeric entity encoding.
There are only two nonalphabetic characters that can begin an XML name: the colon (:) and the underscore (_). Because the colon (:) is already reserved for namespaces, the underscore (_) is chosen as the escape character. The escape rules used for encoding are:
SELECT 'namespace-urn' as 'xmlns:namespace',
1 as 'namespace:a'
FOR XML RAW
The query produces this result:
<row xmlns:namespace="namespace-urn" namespace:a="1"/>
CREATE TABLE MyTable (Col1 int PRIMARY KEY, Col2 binary)
INSERT INTO MyTable VALUES (1, 0x7)
This query produces an error because of the casting to a BLOB:
SELECT Col1,
CAST(Col2 as image) as Col2
FROM MyTable
FOR XML AUTO
If you remove the casting, the query produces results as expected:
SELECT Col1,
Col2
FROM MyTable
FOR XML AUTO
This is the result:
<Computed Col1="1" Col2="dbobject/Computed[@Col1='1']/@Col2"/>
Executing SQL Statements Using HTTP