How to fetch all data from XML column in SQL Server - sql-server

I am trying to fetch the data from a XML column. This is the query and below it is the xml column data
SELECT
[PQDAdvice].value('(/Advice//DORowData/PrimaryValue/node())[1]', 'nvarchar(max)') as PrimaryValue,
[PQDAdvice].value('(/Advice//DORowData/ListValue1/node())[1]', 'nvarchar(max)') as ListValue1
FROM
PatQD
WHERE
PQDPatID = '4c983bd8-da00-4395-80bb-a383b21313d5'
XML contents:
<Advice>
<DORowData>
<PrimaryValue>Diet and Nutrition</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
<DORowData>
<PrimaryValue>Salt Restriction</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
<DORowData>
<PrimaryValue>Water Consumption</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
</Advice>
The issue I am getting that only one column I am getting instead of all column
Primary |ListValue1
Diet and Nutrition |Advice
Instead of
Primary |ListValue1
Diet and Nutrition |Advice
Salt Restriction |Advice
Water Consumption |Advice

DECLARE #xml XML = '
<Advice>
<DORowData>
<PrimaryValue>Diet and Nutrition</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
<DORowData>
<PrimaryValue>Salt Restriction</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
<DORowData>
<PrimaryValue>Water Consumption</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
</Advice>'
SELECT
t.c.value('PrimaryValue[1]', 'nvarchar(max)') as PrimaryValue,
t.c.value('ListValue1[1]', 'nvarchar(max)') as ListValue1
FROM #xml.nodes('Advice/DORowData') t(c)
Output -
PrimaryValue ListValue1
----------------------- ------------
Diet and Nutrition Advice
Salt Restriction Advice
Water Consumption Advice
Your query -
SELECT
PrimaryValue = t.c.value('PrimaryValue[1]', 'NVARCHAR(1000)'),
ListValue1 = t.c.value('ListValue1[1]', 'NVARCHAR(1000)')
FROM PatQD
CROSS APPLY PQDAdvice.nodes('Advice/DORowData') t(c)
where PQDPatID = '4c983bd8-da00-4395-80bb-a383b21313d5'

Try it like this
DECLARE #x XML=
'<Advice>
<DORowData>
<PrimaryValue>Diet and Nutrition</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
<DORowData>
<PrimaryValue>Salt Restriction</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
<DORowData>
<PrimaryValue>Water Consumption</PrimaryValue>
<ListValue1>Advice</ListValue1>
</DORowData>
</Advice>';
SELECT DoRowData.value('PrimaryValue[1]','varchar(max)') AS PrimaryValue
,DoRowData.value('ListValue1[1]','varchar(max)') AS ListValue1
FROM #x.nodes('/Advice/DORowData') AS One(DORowData)

Related

My XML content contains &#xd; why is XSLT 1.0 not converting this into line breaks?

I have multi line text present in an SQL column, and I am fetching the data from an SQL query. My query is inserting at the end of each line.
Query:
Declare #vcFooterText Varchar(max)
Select #vcFooterText = (Select replace(replace(AppConfigValue,CHAR(13),'
'),CHAR(10),'
') From COM.Config_Application With (NoLock) Where AppConfigId = 'PackingNoteFooterText')
Select #vcFooterText
Query Result:
Line 1
Line 2 
Line 3
Then XML is used which is showing the data:
Select tbl.OrderNumber, Cast(
(
'<Documents><Document><PackingNote>' +
Cast((
Select
CustomerName CustomerName,
Convert(Varchar(10), OrderCreatedOn, 103) + ' ' + Convert(Varchar(5), OrderCreatedOn, 114) As OrderDate,
CustomerNumber CustomerNumber,
OrderNumber OrderNumber,
BatchNumber BatchNumber,
ChannelOrderNumber ChannelOrderNumber,
OrderChannel OrderChannel,
Case
When DM.Category = 1501 ANd DM.SubCategory <> 1604 Then 'Click and Collect'
When DM.Category = 1502 Then 'Home Delivery'
End 'OrderType',
#vCompanyName as CompanyName,
#vCompanyEmail as CompanyEmail,
#vCompanyURL as CompanyURL,
#vCollectionPointValue as CollectionPointValue,
Case
when #vCheckCollectionPoint = 'True' Then 'Collection Point'
END 'CollectionPoint',
Case
When DM.Category = 1501 ANd DM.SubCategory <> 1604 Then 'Collect'
When DM.Category = 1502 Then 'Despatch'
When DM.Category = 1501 And DM.SubCategory = 1604 Then (Select AppConfigValue from Catalogue.COM.Config_Application
Where AppConfigId='SameDayShippingLabel')
End 'DeliveryMethod',
(Case When DM.Category = 1502 Then 1 Else 0 End) As 'IsHomeDelivery',
(CASE
WHEN DM.Category = 1502
THEN
CAST(
(
SELECT
ISNULL(OA.Name, CustomerName) CustomerName,
OA.AddressLines AddressLines,
OA.City City,
OA.PostalCode PostalCode,
OA.Country Country
FROM COM.Order_Address OA WITH (NoLock)
INNER JOIN COM.DeliveryMethod DM WITH (NoLock) ON DM.pkDeliveryMethodId = tbl.DeliveryMethodId
AND (DM.Category = 1502
OR DM.SubCategory = 1604) --HomeDelivery
AND OA.OrderId = tbl.OrderId
AND OA.AddressType = 'SHIP'
FOR
XML PATH('')
) AS XML
)
ELSE
CAST(
(
SELECT
ISNULL(B.Name, CustomerName) CustomerName,
A.Street AddressLines,
A.City City,
A.PostalCode PostalCode,
A.County Country
FROM Catalogue..Branch B WITH (NoLock)
INNER JOIN Catalogue.COM.[Order] O WITH (NoLock) ON O.CollectStoreId = B.pkBranchID
INNER JOIN Catalogue..[Address] A WITH (NoLock) ON A.fkBranchID = O.CollectStoreId
INNER JOIN COM.DeliveryMethod DM WITH (NoLock) ON DM.pkDeliveryMethodId = tbl.DeliveryMethodId
AND (DM.Category = 1501
OR DM.SubCategory <> 1604) --CC
AND O.pkOrderId = tbl.OrderId
FOR
XML PATH('')
) AS XML
)
END )
AS 'DeliveryAddress'
From COM.DeliveryMethod DM With (NoLock) Where DM.pkDeliveryMethodId = tbl.DeliveryMethodId
For Xml Path('Header'), Type
) As NVarchar(Max)) +
Cast((
Select SKU As 'Line/SKU',
Quantity As 'Line/Quantity',
ProductName As 'Line/ProductName',
Barcode As 'Line/Barcode',
Price As 'Line/Price'
From #tblPrintOrderLines Where OrderNumber = tbl.OrderNumber
For Xml Path('Lines'), Type
) As Varchar(Max)) +
Cast((
Select SUM(Quantity),
OrderNotes OrderNotes,
#vcFooterText As Text
From #tblPrintOrderLines Where OrderNumber = tbl.OrderNumber
For Xml Path('TotalItems'), Type
) As Varchar(Max)) +
'</PackingNote></Document></Documents>'
)
As XML) As 'XML',
#xmlTemplate As XSLT
From #tblOrderData tbl
XML content:
This is the XML content that is produced:
<Documents>
<Document>
<PackingNote>
<Header>
<CustomerName>laura haines</CustomerName>
<OrderDate>15/09/2017 20:38</OrderDate>
<CustomerNumber>000003</CustomerNumber>
<OrderNumber>000024</OrderNumber>
<BatchNumber>1 of 1</BatchNumber>
<OrderType>Click and Collect</OrderType>
<CompanyName>The Retail Suite</CompanyName>
<CompanyURL />
<DeliveryMethod>Collect</DeliveryMethod>
<IsHomeDelivery>0</IsHomeDelivery>
<DeliveryAddress>
<CustomerName>ACC</CustomerName>
<AddressLines>London</AddressLines>
<City>London</City>
</DeliveryAddress>
</Header>
<Lines>
<Line>
<SKU>000044</SKU>
<Quantity>9</Quantity>
<ProductName>Partial Cancel 001</ProductName>
<Price>135.00</Price>
</Line>
</Lines>
<TotalItems>9<Text>Line 1&#xD;Line 2 &#xD;Line 3</Text></TotalItems>
</PackingNote>
</Document>
</Documents>
How I can get line breaks using XSL 1.0?
XSLT 1.0:
<fo:table-row>
<fo:table-cell padding-bottom="1mm" padding-left="0.5cm">
<fo:block font-size="10pt" text-align="left">
<xsl:value-of select="text" />
</fo:block>
</fo:table-cell>
</fo:table-row>
Current output:
Line 1
Line 2 
Line 3
Expected Output:
Line 1
Line 2
Line 3
If you're using XSLT 1.0, replace this line:
<xsl:value-of select="text" />
with:
<xsl:call-template name="replace">
<xsl:with-param name="text" select="text"/>
</xsl:call-template>
and add this to your stylesheet:
<xsl:template name="replace">
<xsl:param name="text"/>
<xsl:param name="search-string" select="'&#xD;'"/>
<xsl:param name="replace-string" select="'
'"/>
<xsl:choose>
<xsl:when test="contains($text, $search-string)">
<xsl:value-of select="substring-before($text, $search-string)"/>
<xsl:value-of select="$replace-string"/>
<xsl:call-template name="replace">
<xsl:with-param name="text" select="substring-after($text, $search-string)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Note: XML is case-sensitive, and in your XML the element is named Text not text. So it should really be:
<xsl:call-template name="replace">
<xsl:with-param name="text" select="Text"/>
</xsl:call-template>
How I can get line breaks using XSL 1.0?
In your query, you can replace the CHAR with
OR
instead of
OR
In XSLT 1.0, you can do the same as below:
<fo:table-row>
<fo:table-cell padding-bottom="1mm" padding-left="0.5cm">
<fo:block font-size="10pt" text-align="left">
<xsl:value-of select="translate(text,'&#xd;','
')" />
</fo:block>
</fo:table-cell>
</fo:table-row>
XSLT would convert
OR
in line breaks. Refer to the updated transformation here.
To correct:
In XSLT 1.0, it's needed to write a recursive template to replace a string or xmlns:str="xalan://org.apache.commons.lang.StringUtils" can be used, which provides the `replace()' method.

TSQL CTE hierarchy

I am trying to create a CTE on my table to pull in a hierarchy of employees.
I have a starting point which is a "Director" and I want to find everyone that reports to each person under them.
Here is what I have so far:
;WITH EmpTable_CTE (FirstName, LastName, QID, Email) AS
(
SELECT FirstName,
LastName,
QID,
Email
FROM EmployeeTable E
WHERE QID = '12345'
UNION ALL
SELECT E.FirstName,
E.LastName,
E.QID,
E.Email
FROM EmployeeTable E
INNER JOIN EmpTable_CTE AS E2 ON E.MgrQID = E2.QID
)
SELECT * FROM EmpTable_CTE
This seems to work providing me a list of employees but there is no "hierarchy" to it.
How can I go about using FOR XML to create the hierarchy that I am looking for?
<Director>Bob Smith</Director>
<Direct>Jim Smith</Direct>
<Direct>Employee 1</direct>
<Direct>Employee 2</direct>
<Direct>Employee 3</direct>
<Direct>Bob Jones</Direct>
<Direct>Employee 1</direct>
<Direct>Employee 2</direct>
<Direct>Employee 3</direct>
<Direct>Employee A</direct>
I'm sure its just a matter of placing the FOR XML line somewhere but cant quite figure it out.
Update: Here is a SQL Fiddle of sample data:
http://sqlfiddle.com/#!6/a48f6/1
This is how I would expect the data to be from the fiddle:
<Director>Jim Jones</Director>
<Direct>Bob Jones</Direct>
<Direct>Jake Jones</Direct>
<Direct>Smith Jones</Direct>
<Direct>Carl Jones</Direct>
<Direct>Bobby Jones</Direct>
<Direct>Danny Jones</Direct>
<Direct>Billy Jones</Direct>
Part of the difficulty is in the XML structure you presented - If you passed that into a parser, it would all be flat, and running the results of my process below without stuffing the First and Last name into an attribute made the nodes come out in mixed content (text with nodes on the same level).
So, I went searching and found this little gem here on SE. Adapting it to your needs, and throwing in a few fields as attributes from your table, I came up with this:
CREATE FUNCTION dbo.EmpHierarchyNode(#QID int)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
BEGIN RETURN
(SELECT QID AS "#ID", Email AS "#Email",
FirstName + ' ' + LastName AS "#Name",
CASE WHEN MgrQID = #QID
THEN dbo.EmpHierarchyNode(QID)
END
FROM dbo.EmployeeTable
WHERE MgrQID = #QID
FOR XML PATH('Direct'), TYPE)
END
SELECT QID AS "#ID", Email AS "#Email",
FirstName + ' ' + LastName AS "#Name",
dbo.EmpHierarchyNode(QID)
FROM dbo.EmployeeTable
WHERE MgrQID IS NULL
FOR XML PATH('Director'), TYPE
Essentially, this traverses down in the hierarchy, recursively calling itself. The CTE isn't sufficient if your output is targeted for XML. Using this, and what I could glean of your sample data, I got this as a result:
<Director ID="1" Email="bsmith#someCompany.com" Name="Bob Smith">
<Direct ID="2" Email="jsmith#someCompany.com" Name="Jim Smith">
<Direct ID="4" Email="e1#someCompany.com" Name="Employee 1" />
<Direct ID="5" Email="e2#someCompany.com" Name="Employee 2" />
<Direct ID="7" Email="e4#someCompany.com" Name="Employee 4" />
</Direct>
<Direct ID="3" Email="bjones#someCompany.com" Name="Bob Jones">
<Direct ID="6" Email="e3#someCompany.com" Name="Employee 3" />
<Direct ID="8" Email="e5#someCompany.com" Name="Employee 5" />
<Direct ID="9" Email="e6#someCompany.com" Name="Employee 6" />
</Direct>
</Director>
Hope this helps.
EDIT: Last Minute SQLFiddle Example.
See if it meets yours requirement:
;WITH EmpTable_CTE (FirstName, LastName, QID, Email) AS
(
SELECT FirstName,
LastName,
QID,
Email
FROM EmployeeTable E
WHERE QID = 1
UNION ALL
SELECT E.FirstName,
E.LastName,
E.QID,
E.Email
FROM EmployeeTable E
INNER JOIN EmpTable_CTE AS E2
ON E.MgrQID = E2.QID
)
SELECT LastName + ', ' + FirstName FROM EmpTable_CTE FOR XML PATH('Direct'), ROOT('Director'), TYPE

XML PATH in SQL SERVER how to NEST

I'm new to using XML and I think this is an easy question, but i just can't get the format correct.
I'm trying to get this output
<Contracts>
<Contract>
<Ref>P000006-140</Ref>
<ReportingTransactionAmountEntry>
<TechAccountAmtItem>
<Amt Ccy="GBP">7500.0000</Amt>
</TechAccountAmtItem>
</ReportingTransactionAmountEntry>
</Contract>
<Contract>
<Ref>P000006-140</Ref>
<ReportingTransactionAmountEntry>
<TechAccountAmtItem>
<Amt Ccy="GBP">100.0000</Amt>
</TechAccountAmtItem>
<TechAccountAmtItem>
<Amt Ccy="GBP">7600.0000</Amt>
</TechAccountAmtItem>
</ReportingTransactionAmountEntry>
</Contract>
<Contract>
<Ref>P000006-140</Ref>
<ReportingTransactionAmountEntry>
<TechAccountAmtItem>
<Amt Ccy="EUR">500.0000</Amt>
</TechAccountAmtItem>
</ReportingTransactionAmountEntry>
</Contract>
</Contracts>
to look like this,
with the contact Reference only showing once at a higher level
<Contracts>
<Contract>
<Ref>P000006-140</Ref>
<ReportingTransactionAmountEntry>
<TechAccountAmtItem>
<Amt Ccy="GBP">7500.0000</Amt>
</TechAccountAmtItem>
</ReportingTransactionAmountEntry>
<ReportingTransactionAmountEntry>
<TechAccountAmtItem>
<Amt Ccy="GBP">100.0000</Amt>
</TechAccountAmtItem>
<TechAccountAmtItem>
<Amt Ccy="GBP">7600.0000</Amt>
</TechAccountAmtItem>
</ReportingTransactionAmountEntry>
<ReportingTransactionAmountEntry>
<TechAccountAmtItem>
<Amt Ccy="EUR">500.0000</Amt>
</TechAccountAmtItem>
</ReportingTransactionAmountEntry>
</Contract>
</Contracts>
my query looks like this
SELECT
RTRIM(PolicyRef) AS 'Ref',
(SELECT * FROM
(
select
RTRIM(SettlementCurrency) AS 'TechAccountAmtItem/Amt/#Ccy',
Paid_This_Time_Indemnity AS 'TechAccountAmtItem/Amt'
UNION
SELECT
RTRIM(SettlementCurrency) AS 'TechAccountAmtItem/Amt/#Ccy',
Paid_To_Date_Indemnity AS 'TechAccountAmtItem/Amt'
) iq FOR XML PATH(''),TYPE
) AS 'ReportingTransactionAmountEntry'
FROM #tmpClm3
FOR XML PATH ('Contract'),ROOT('Contracts')
any help would be greatly appreciated.
You need to group on PolicyRef in the main query and get the details in a sub-query.
select T1.PolicyRef as [Ref],
(
select
(
select T2.SettlementCurrency as [TechAccountAmtItem/Amt/#Ccy],
T2.Paid_This_Time_Indemnity as [TechAccountAmtItem/Amt]
where T2.Paid_This_Time_Indemnity is not null
for xml path(''), type
),
(
select T2.SettlementCurrency as [TechAccountAmtItem/Amt/#Ccy],
T2.Paid_To_Date_Indemnity as [TechAccountAmtItem/Amt]
where T2.Paid_To_Date_Indemnity is not null
for xml path(''), type
)
from T as T2
where T1.PolicyRef = T2.PolicyRef
for xml path('ReportingTransactionAmountEntry'), type
)
from T as T1
group by T1.PolicyRef
for xml path('Contract'), root('Contracts')
SQL Fiddle

XQuery parent and child

Example:
DECLARE #XML XML = '
<Items>
<document id="doc1" value="100">
<details>
<detail detailID="1" detailValue="20"/>
<detail detailID="2" detailValue="80"/>
</details>
</document>
<document id="doc2" value="0">
<details>
</details>
</document>
</Items>
'
I want results like this:
id value detailID detailValue
doc1 100 1 20
doc1 100 2 80
doc2 0 NULL NULL
Tried:
SELECT document.value('../../#docID', 'VARCHAR(10)') AS 'docID',
document.value('../../#value', 'INT') AS 'value',
document.value('#detailID', 'VARCHAR(10)') AS 'detailID',
document.value('#detailValue', 'INT') AS 'detailValue'
FROM #XML.nodes('Items/document/details/detail') AS Documents(document)
But, doc2 is not listed... Also, tried with CROSS JOIN and INNER JOIN, but performance is very bad.
Try this:
SELECT document.value('#id', 'VARCHAR(10)') AS docID,
document.value('#value', 'INT') AS value,
Detail.value('#detailID', 'INT') as DetailId,
Detail.value('#detailValue', 'INT') as DetailValue
FROM #XML.nodes('Items/document') AS Documents(document)
outer apply Documents.document.nodes('details/detail') as Details(Detail);
Just one added detail:
#XML.nodes('//whatever_depth') AS Documents(document)
Using '//' Allows you to query not directly from root
Regards,
Dennes

TSQL FOR XML EXPLICIT

Not able to to get the desired XML output
The following:
SELECT 1 as Tag,
0 as Parent,
sID as [Document!1!sID],
docID as [Document!1!docID],
null as [To!2!value]
FROM docSVsys with (nolock)
where docSVsys.sID = '57'
UNION ALL
SELECT 2 as Tag,
1 as Parent,
sID,
NULL,
value
FROM docMVtext
WHERE docMVtext.sID = '57'
ORDER BY [Document!1!sID],[To!2!value]
FOR XML EXPLICIT;
Produces:
<Document sID="57" docID="3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA">
<To value="Frank Ermis" />
<To value="Keith Holst" />
<To value="Mike Grigsby" />
</Document>
What I want is:
<Document sID="57">
<docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA</docID>
<To>
<Value>Frank Ermis</Value>
<Value>Keith Holst</Value>
<Value>Mike Grigsby</Value>
</To>
</Document>
Can I get that ouput with FOR XML?
Ok I get they may be technically equivalent.
What I want and what I need are not the same.
Using xDocument for this is is SLOW.
There are millions of documents and need to XML up to 1 million at a time to XML.
The TSQL FOR XML is super fast.
I just need to get FOR XML to format.
The solution (based on accepted answer):
SELECT top 4
[sv].[sID] AS '#sID'
,[sv].[sParID] AS '#sParID'
,[sv].[docID] AS 'docID'
,[sv].addDate as 'addDate'
,(SELECT [value] AS 'value'
FROM [docMVtext] as [mv]
WHERE [mv].[sID] = [sv].[sID]
AND [mv].[fieldID] = '113'
ORDER BY [mv].[value]
FOR XML PATH (''), type
) AS "To"
,(SELECT [value] AS 'value'
FROM [docMVtext] as [mv]
WHERE [mv].[sID] = [sv].[sID]
AND [mv].[fieldID] = '130'
ORDER BY [mv].[value]
FOR XML PATH (''), type
) AS "MVtest"
FROM [docSVsys] as [sv]
WHERE [sv].[sID] >= '57'
ORDER BY
[sv].[sParID], [sv].[sID]
FOR XML PATH('Document'), root('Documents')
Produces:
<Documents>
<Document sID="57" sParID="57">
<docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA</docID>
<addDate>2011-10-28T12:26:00</addDate>
<To>
<value>Frank Ermis</value>
<value>Keith Holst</value>
<value>Mike Grigsby</value>
</To>
<MVtest>
<value>MV test 01</value>
<value>MV test 02</value>
<value>MV test 03</value>
<value>MV test 04</value>
</MVtest>
</Document>
<Document sID="58" sParID="57">
<docID>3.818919.C41P3UKK00BRICLAY0AR1ET2EBPYSU4SA.1</docID>
<addDate>2011-10-28T12:26:00</addDate>
</Document>
<Document sID="59" sParID="59">
<docID>3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA</docID>
<addDate>2011-10-28T12:26:00</addDate>
<To>
<value>Vladimir Gorny</value>
</To>
</Document>
<Document sID="60" sParID="59">
<docID>3.818920.KJKP5LYKTNIODOEI4JDOKJ2BXJI5P0BIA.1</docID>
<addDate>2011-10-28T12:26:00</addDate>
</Document>
</Documents>
Now what I need to do is to add a DispName attribute to the element MVtext. Attribute cannot have any spaces and I would like to include the friendly name e.g. Multi Value Text.
Try something like this (untested, since I don't have your database tables to test against...):
SELECT
sv.sID AS '#sID',
sv.docID AS 'docID',
(SELECT
value AS 'value'
FROM
dbo.docMVtext mv
WHERE
mv.sID = sv.sID
ORDER BY mv.value
FOR XML PATH (''), TYPE) AS 'To'
FROM
dbo.docSVsys sv
WHERE
sv.sID = '57'
ORDER BY
sv.sID
FOR XML PATH('Document')
Does that give you what you're looking for?? And don't you agree with John and me: this is much simpler than FOR XML EXPLICIT.....
From Examples: Using PATH Mode:
USE AdventureWorks2008R2;
GO
SELECT ProductModelID AS "#ProductModelID",
Name AS "#ProductModelName",
(SELECT ProductID AS "data()"
FROM Production.Product
WHERE Production.Product.ProductModelID =
Production.ProductModel.ProductModelID
FOR XML PATH ('')
) AS "#ProductIDs",
(
SELECT Name AS "ProductName"
FROM Production.Product
WHERE Production.Product.ProductModelID =
Production.ProductModel.ProductModelID
FOR XML PATH (''), type
) AS "ProductNames"
FROM Production.ProductModel
WHERE ProductModelID= 7 OR ProductModelID=9
FOR XML PATH('ProductModelData');

Resources