SQL- fetch value from XML parent node (separately) - sql

In my below Query it's return all the recode set as a XML into a single variable.But i need all the parent node values into separate while loop.Just run the below query:
---------Just Declare the temp Table -------------------------------------------------
IF OBJECT_ID('tempdb.dbo.##TestTable','U')IS NOT NULL DROP TABLE ##TestTable
CREATE TABLE ##TestTable(id int,Uname nvarchar(max),Uaddress nvarchar(max))
INSERT INTO ##TestTable values (1,'abc','NY')
INSERT INTO ##TestTable values (2,'def','WD')
INSERT INTO ##TestTable values (3,'','KL')
DECLARE #XML XML
DECLARE #WhereClause nvarchar(max)
DECLARE #CountVal int
SELECT #CountVal=count(*) from ##TestTable
SET #XML= (SELECT * FROM ##TestTable FOR XML PATH('ParentNode'), ELEMENTS XSINIL)
SELECT #XML
;with cte as
( select xr.value('fn:local-name(.)','nvarchar(max)') name, xr.value('.','nvarchar(max)') val from #xml.nodes('//.') xq(xr)
where xr.value('fn:local-name(.)','nvarchar(max)')<>''
)
SELECT #WhereClause= STUFF((select ' and ' + name + '='''+val+'''' from cte for xml path('')),1,4,'')
SELECT #WhereClause
WHILE (#CountVal>0)
BEGIN
SELECT #WhereClause
SET #CountVal=#CountVal-1
END
IF OBJECT_ID('tempdb.dbo.##TestTable','U')IS NOT NULL DROP TABLE ##TestTable
Current sample XML(in #XML):
<ParentNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><id>1</id><Uname>abc</Uname><Uaddress>NY</Uaddress></ParentNode><ParentNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><id>2</id><Uname>def</Uname><Uaddress>WD</Uaddress></ParentNode><ParentNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><id>3</id><Uname /><Uaddress>KL</Uaddress></ParentNode>
Current the output of #WhereClause is (all into in a single #WhereClause variable):
ParentNode='1abcNY' and id='1' and Uname='abc' and Uaddress='NY' and ParentNode='2defWD' and id='2' and Uname='def' and Uaddress='WD' and ParentNode='3KL' and id='3' and Uname='' and Uaddress='KL'
But my Expected output is:
Firstly(in #WhereClause): id='1' and Uname='abc' and Uaddress='NY'
Secondly(in #WhereClause):id='2' and Uname='def' and Uaddress='WD'
Thirdly(in #WhereClause):id='3' and Uname='' and Uaddress='KL'
.
.
How i get it. Thanks in advance.

Try this:
declare #WhereClause nvarchar(max)
declare #CountVal int
select #CountVal=count(*)
from ##TestTable
while #CountVal>0
begin
select #WhereClause =
(
select ' and '+T.N.value('local-name(.)', 'nvarchar(max)')+'='+T.N.value('.', 'nvarchar(max)')
from (
select *
from ##TestTable
where id = #CountVal
for xml path(''), type
) as C(X)
cross apply C.X.nodes('/*') as T(N)
for xml path(''), type
).value('substring((./text())[1], 6)', 'nvarchar(max)')
select #WhereClause
set #CountVal=#CountVal-1
end

seem to be late and having missunderstood, that woul habe been my approach
DECLARE #XML XML
DECLARE #WhereClause nvarchar(max)
DECLARE #CountVal int
SELECT #CountVal=count(*) from ##TestTable
SET #XML= (SELECT * FROM ##TestTable FOR XML PATH('ParentNode'), ELEMENTS XSINIL)
SELECT #XML
;with cte as
( select xr.value('fn:local-name(.)','nvarchar(max)') name, xr.value('.','nvarchar(max)') val from #xml.nodes('//.') xq(xr)
where xr.value('fn:local-name(.)','nvarchar(max)')<>'' and xr.value('fn:local-name(.)','nvarchar(max)')<>'ParentNode'
)
SELECT #WhereClause= SubString((select Case when Name ='id' then CHAR(10) +''+ name + '='''+val+'''' else ' and ' + name + '='''+val+'''' end from cte for xml path('')),2,100000000)
Print #WhereClause

Related

Returning all child nodes as columns from XML in Sql Server

I am doing the following to select nodes from an XML string, the first part is just to show you what I'm selecting from.
The issue is I want to do this for various different XML columns and I'd like to not have to specify the node name for each column in my select, is there a way to select all nodes as columns automatically or even a cursor using count?
DECLARE #MyXML XML
SET #MyXML = (SELECT
CAST (
'<AllowAdd>N</AllowAdd>
<Allowed>NUMSEG</Allowed>
<AllSegmentsEqualValue>N</AllSegmentsEqualValue>
<ClusterLevelSA>Y</ClusterLevelSA>
<ClusterLevelPremium>Y</ClusterLevelPremium>
<AllowAssignedAndInTrust>N</AllowAssignedAndInTrust>
<MinSegments>1</MinSegments>
<MaxSegments>100</MaxSegments>
<DefaultSegments>10</DefaultSegments>
<RoundPremiumsTo>2</RoundPremiumsTo>
<TaxDeferredAllowance>0.05</TaxDeferredAllowance>
<HigherTaxValueBands>HTVB</HigherTaxValueBands>
<NumberYearsCalculationType>NONFIN</NumberYearsCalculationType>
<OnShore>POLICY</OnShore>
<OffShore>NONFIN</OffShore>'as XML) as x)
SELECT
Data.Col.value('(/AllowAdd)[1]','Varchar(10)') as [Allow Addition of]
,Data.Col.value('(/Allowed)[1]','Varchar(10)') as [Allowed]
,Data.Col.value('(/MinSegments)[1]','Int') as [Min Segments]
,Data.Col.value('(/MaxSegments)[1]','Int') as [Max Segments]
,Data.Col.value('(/DefaultSegments)[1]','Int') as [Default Segments]
,Data.Col.value('(/RoundPremiumsTo)[1]','Int') as [Round Premiums To]
,Data.Col.value('(/AllSegmentsEqualValue)[1]','Varchar(10)') as [All Segments Equal Value]
--,Data.Col.value('(/TaxDeferredAllowance)[1]','Varchar(10)') as [Tax Deferred Allowance]
,Data.Col.value('(/HigherTaxValueBands)[1]','Varchar(10)') as [Higher Tax Value Bands]
,Data.Col.value('(/NumberYearsCalculationType)[1]','Varchar(10)') as [Number Years Calculation Type]
,Data.Col.value('(/OnShore)[1]','Varchar(10)') as [OnShore]
,Data.Col.value('(/OffShore)[1]','Varchar(10)') as [OffShore]
FROM #MyXML.nodes('/OffShore') AS Data(Col)
I hope, this is what you are waiting for :)
DECLARE #MyXML XML
SET #MyXML = (SELECT
CAST (
'<AllowAdd>N</AllowAdd>
<Allowed>NUMSEG</Allowed>
<AllSegmentsEqualValue>N</AllSegmentsEqualValue>
<ClusterLevelSA>Y</ClusterLevelSA>
<ClusterLevelPremium>Y</ClusterLevelPremium>
<AllowAssignedAndInTrust>N</AllowAssignedAndInTrust>
<MinSegments>1</MinSegments>
<MaxSegments>100</MaxSegments>
<DefaultSegments>10</DefaultSegments>
<RoundPremiumsTo>2</RoundPremiumsTo>
<TaxDeferredAllowance>0.05</TaxDeferredAllowance>
<HigherTaxValueBands>HTVB</HigherTaxValueBands>
<NumberYearsCalculationType>NONFIN</NumberYearsCalculationType>
<OnShore>POLICY</OnShore>
<OffShore>NONFIN</OffShore>'as XML) as x)
DECLARE #Output nvarchar(max) = N''
DECLARE #PivotList nvarchar(max)
SELECT
#PivotList = COALESCE(#PivotList + ', ', N'') + N'[' + XC.value('local-name(.)', 'varchar(100)') + N']'
FROM
#MyXML.nodes('/*') AS XT(XC)
SET #Output = N'SELECT
'+#PivotList+N'
FROM
(
SELECT
ColName = XC.value(''local-name(.)'', ''nvarchar(100)''),
ColValue = ISNULL(NULLIF(CONVERT(nvarchar(max),XC.query(''./*'')),''''),XC.value(''.'',''nvarchar(max)''))
FROM
#MyXML.nodes(''/*'') AS XT(XC)
) AS s
PIVOT
(
MAX(ColValue)
FOR ColName IN ('+#PivotList+N')
) AS t;'
EXEC sp_executesql #Output, N'#MyXml xml', #MyXML = #MyXML;
Given your input XML, you can try to use this:
SELECT
ColName = XC.value('local-name(.)', 'varchar(100)'),
ColValue = xc.value('(.)[1]', 'varchar(100)')
FROM
#MyXML.nodes('/*') AS XT(XC)
This will output each XML element found under the root - its name and value - as a list:
Of course, since it's a very generic approach, you cannot really define the proper datatypes for each columns in the second xc.value() - you basically get everything as a string.
Using a cursor to build a SELECT statement and sp_executesql to execute it!
DECLARE #MyXML XML
DECLARE #FieldName VARCHAR(MAX)
DECLARE #SELECT_TEXT NVARCHAR(MAX)
SET #MyXML = (SELECT
CAST (
'<AllowAdd>N</AllowAdd>
<Allowed>NUMSEG</Allowed>
<AllSegmentsEqualValue>N</AllSegmentsEqualValue>
<ClusterLevelSA>Y</ClusterLevelSA>
<ClusterLevelPremium>Y</ClusterLevelPremium>
<AllowAssignedAndInTrust>N</AllowAssignedAndInTrust>
<MinSegments>1</MinSegments>
<MaxSegments>100</MaxSegments>
<DefaultSegments>10</DefaultSegments>
<RoundPremiumsTo>2</RoundPremiumsTo>
<TaxDeferredAllowance>0.05</TaxDeferredAllowance>
<HigherTaxValueBands>HTVB</HigherTaxValueBands>
<NumberYearsCalculationType>NONFIN</NumberYearsCalculationType>
<OnShore>POLICY</OnShore>
<OffShore>NONFIN</OffShore>
'
as XML) as x)
SET #SELECT_TEXT = 'SELECT '
DECLARE xml_cursor CURSOR
FOR SELECT Data.Col.value( 'fn:local-name(.)', 'VARCHAR(MAX)' ) FROM #MyXML.nodes('/*') AS Data(Col)
open xml_cursor
While 1 = 1
BEGIN
fetch next from xml_cursor into #FieldName
if ##fetch_status <> 0
begin
break
end
SET #SELECT_TEXT = #SELECT_TEXT + 'Data.Col.value(''(/' + #FieldName + ')[1]'',''Varchar(MAX)'') as [' + #FieldName + ']' + ', '
END
close xml_cursor
deallocate xml_cursor
SET #SELECT_TEXT = SUBSTRING( #SELECT_TEXT,0, LEN(#SELECT_TEXT) ) + 'FROM #MyXML.nodes(''/OffShore'') AS Data(Col)'
EXECUTE sp_executesql #SELECT_TEXT, N'#MyXML XML', #MyXML = #MyXML
As previously mentioned in another comment the drawback is not having column types but it's for a report style query so strings is ok.

Returning the results of a select statement that uses a FOR XML PATH('') to condense to one row in a Stored Procedure

I need to pull several values out of some XML that I have and return it as one string from a stored procedure. I have created the select statement that will pull all of the rows into one.
This is the code that I currently have.
CREATE FUNCTION openrpt.getSearchTermNames (#searchID NVARCHAR(MAX))
RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE #xmlData XML
DECLARE #Names XML
SET #xmlData =
(
SELECT QueryXML
FROM ConflictsSearchTerms
WHERE ConflictsSearchTerms.[ID] = #searchID);
WITH xmlnamespaces ( default 'http://schemas.datacontract.org/2004/07/IntApp.Wilco.Model.Conflicts.Searches', 'http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS d2p1, 'http://www.w3.org/2001/XMLSchema-instance' AS i )
RETURN
(
SELECT '; ' + temp.value('.', 'NVARCHAR(MAX)')
FROM #xmlData.nodes('/ConflictsSearchTermQuery/TermItems/d2p1:string') AS XMLDATA(temp)
UNION
SELECT '; ' + temp.value('d2p1:Value[1]', 'NVARCHAR(MAX)') AS [Test]
FROM #xmlData.nodes('/ConflictsSearchTermQuery/CorporateTreeCompaniesById/d2p1:KeyValueOfstringstring') AS XMLDATA(temp) FOR XML PATH('')
)
The select statemt will correctly return a list of the items from those two fields in the XML seperated by semi-colons but I am getting a syntax error at the return . I also get an error that says
The FOR XML clause is invalid in views, inline functions, derived tables, and subqueries when they contain a set operator. To work around, wrap the SELECT containing a set operator using derived table syntax and apply FOR XML on top of it.
Try this:
CREATE FUNCTION openrpt.getSearchTermNames
(
#searchID NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #xmlData XML
DECLARE #Names XML
DECLARE #x XML
SET #xmlData = ( SELECT QueryXML
FROM ConflictsSearchTerms
WHERE ConflictsSearchTerms.[ID] = #searchID
);
WITH XMLNAMESPACES ( DEFAULT 'http://schemas.datacontract.org/2004/07/IntApp.Wilco.Model.Conflicts.Searches', 'http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS d2p1, 'http://www.w3.org/2001/XMLSchema-instance' AS i )
SELECT #x =
( SELECT * FROM (
SELECT '; ' + temp.value('.', 'NVARCHAR(MAX)') AS [Test]
FROM #xmlData.nodes('/ConflictsSearchTermQuery/TermItems/d2p1:string') AS XMLDATA(temp)
UNION
SELECT '; ' + temp.value('d2p1:Value[1]', 'NVARCHAR(MAX)')
FROM #xmlData.nodes('/ConflictsSearchTermQuery/CorporateTreeCompaniesById/d2p1:KeyValueOfstringstring') AS XMLDATA(temp))t
FOR XML PATH('')
)
RETURN CAST(#x AS NVARCHAR(MAX))
END

Convert a column value into series of rows and columns in SQL [duplicate]

This question already has answers here:
Parsing a string SQL
(3 answers)
Closed 8 years ago.
I have a table in which one column is having data like as below:
column value='A,B,C,D,E,F
XA123,Name1,10/20,1.11,27-03-2014,414BJE
XA154,Name2,10/10,1.143,26-03-2014,414B32
XA134,Name21,10/50,1.123,27-03-2014,414B534E
XA125,Name32,20/20,1.1234,17-02-2014,414BJ3
XA124,Name43,30/20,1.165,23-02-2014,414B432
XA1256,Name324,50/60,4.31,07-01-2014,4GHH
XA1252,Name32,70/60,6.61,09-12-2013,414B2E'
Now i need this column value to be sorted out like that in a separate table.
Expected Output:
A B C D E F
XA123 Name1 10/20 1.11 27-03-2014 414BJE
XA154 Name2 10/10 1.143 26-03-2014 414B32
XA134 Name21 10/50 1.123 27-03-2014 414B534E
XA125 Name32 20/20 1.1234 17-02-2014 414BJ3
XA124 Name43 30/20 1.165 23-02-2014 414B432
XA1256 Name324 50/60 4.31 07-01-2014 4GHH
XA1252 Name32 70/60 6.61 09-12-2013 414B2E
Edit:
To get the above solution, at first, i divided column value based on new line character and inserted into a new table variable:
Declare #value nvarchar(max) ='A,B,C,D,E,F
XA123,Name1,10/20,1.11,27-03-2014,414BJE
XA154,Name2,10/10,1.143,26-03-2014,414B32
XA134,Name21,10/50,1.123,27-03-2014,414B534E
XA125,Name32,20/20,1.1234,17-02-2014,414BJ3
XA124,Name43,30/20,1.165,23-02-2014,414B432
XA1256,Name324,50/60,4.31,07-01-2014,4GHH
XA1252,Name32,70/60,6.61,09-12-2013,414B2E'
Declare #t Table
(
Id int identity(1,1),
Val VARCHAR(max)
)
while (charindex(char(13),#value)>0)
BEGIN
insert into #t (Val)
select substring(#value,1,charindex(char(13),#value))
set #value = (select substring(#value,charindex(char(13),#value)+1,len(#value)))
END
select * from #t
Then i created a new table variable and separated value for each row of #t table variable based on ','. Now hoping to get a generic and better solution.
Edited again:
Here I am trying to make a generic solution for this issue..lets say values in these rows can go to any number, for ex:
A,B,C,D,E,F could be
A,B,C,D,E,F,G
A,B,C,D,E,F,G,H
A,B,C,D,E,F,G,H....Z
so i am trying to get solution using dynamic query in below code, but getting an error: Must declare the scalar variable "#xml"
Declare #value nvarchar(max) ='A,B,C,D,E,F,G
XA123,Name1,10/20,1.11,27-03-2014,414BJE,afs
XA154,Name2,10/10,1.143,26-03-2014,414B32,ag
XA134,Name21,10/50,1.123,27-03-2014,414B534E,GSF
XA125,Name32,20/20,1.1234,17-02-2014,414BJ3,GG
XA124,Name43,30/20,1.165,23-02-2014,414B432,GS
XA1256,Name324,50/60,4.31,07-01-2014,4GHH,GS
XA1252,Name32,70/60,6.61,09-12-2013,414B2E,sg'
declare #query varchar(max)
declare #xml xml
declare #count int
declare #i int = 1
select #xml = '<item><value>'+replace(replace(#value, ',','</value><value>'), char(10),'</value></item><item><value>')+'</value></item>'
DECLARE #XmlTable TABLE (XmlResult XML)
INSERT INTO #XmlTable select #xml
set #count = (SELECT XmlResult.value('count(/item/value)', 'int')/XmlResult.value('count(/item)', 'int') FROM #XmlTable)
SET #query = 'select '
WHILE (#i <= #count)
BEGIN
IF(#i!=1)
BEGIN
set #query = #query + ', '
END
set #query = #query + 'N.value(''substring(value['+ cast(#i as varchar) +'],1)'',''varchar(10)'')'
SET #i = #i + 1
END
set #query = #query + ' from ' + '#xml.nodes' + '(''item'') as T(N)'
-- select #query
EXEC(#query)
Guys, any suggestion...
Here it is...
Declare #value nvarchar(max) ='A,B,C,D,E,F
XA123,Name1,10/20,1.11,27-03-2014,414BJE
XA154,Name2,10/10,1.143,26-03-2014,414B32
XA134,Name21,10/50,1.123,27-03-2014,414B534E
XA125,Name32,20/20,1.1234,17-02-2014,414BJ3
XA124,Name43,30/20,1.165,23-02-2014,414B432
XA1256,Name324,50/60,4.31,07-01-2014,4GHH
XA1252,Name32,70/60,6.61,09-12-2013,414B2E'
declare #xml xml
select #xml = '<item><value>'+replace(replace(#value, ',','</value><value>'), char(13),'</value></item><item><value>')+'</value></item>'
select
N.value('substring(value[1],1)', 'varchar(10)') as V1,
N.value('substring(value[2],1)', 'varchar(10)') as V2,
N.value('substring(value[3],1)', 'varchar(10)') as V3,
N.value('substring(value[4],1)', 'varchar(10)') as V4,
N.value('substring(value[5],1)', 'varchar(10)') as V5,
N.value('substring(value[6],1)', 'varchar(10)') as V6
from #xml.nodes('item') as T(N)
Try this, First Create a Scalar function AS
Create FUNCTION [dbo].[funcSplit_OneVal]
(
#param NVARCHAR(MAX),
#delimiter CHAR(1),
#nThVal int
)
RETURNS varchar(50)
--select dbo.funcSplit_OneVal('1,2,3,4',',',5)
AS
BEGIN
Declare #t TABLE (val NVARCHAR(MAX))
Declare #retVal varchar(50) = ''
SET #param += #delimiter
;WITH a AS
(
SELECT CAST(1 AS BIGINT) f,
CHARINDEX(#delimiter, #param) t,
1 seq
UNION ALL
SELECT t + 1,
CHARINDEX(#delimiter, #param, t + 1),
seq + 1
FROM a
WHERE CHARINDEX(#delimiter, #param, t + 1) > 0
)
INSERT #t
SELECT SUBSTRING(#param, f, t - f)
FROM a
OPTION(MAXRECURSION 0)
select top (#nThVal) #retVal =val from #t
RETURN #retVal
END
Then Execute following Script,
Declare #value nvarchar(max) ='A,B,C,D,E,F
XA123,Name1,10/20,1.11,27-03-2014,414BJE
XA154,Name2,10/10,1.143,26-03-2014,414B32
XA134,Name21,10/50,1.123,27-03-2014,414B534E
XA125,Name32,20/20,1.1234,17-02-2014,414BJ3
XA124,Name43,30/20,1.165,23-02-2014,414B432
XA1256,Name324,50/60,4.31,07-01-2014,4GHH
XA1252,Name32,70/60,6.61,09-12-2013,414B2E'
DECLARE #xml AS XML = CAST(('<X>'+REPLACE(#value,' ' ,'</X><X>')+'</X>') AS XML)
;With CTE as
(
SELECT C.value('.', 'varchar(250)') AS value
FROM #xml.nodes('X') as X(C)
)
select dbo.funcSplit_OneVal(value,',',1)
,dbo.funcSplit_OneVal(value,',',2)
,dbo.funcSplit_OneVal(value,',',3)
,dbo.funcSplit_OneVal(value,',',4)
,dbo.funcSplit_OneVal(value,',',5)
,dbo.funcSplit_OneVal(value,',',6)
from CTE
where len(value) > 0
If required then you can remove 'A,B,C... from variable & give alise in Last Select.

SQL Variable in XML Node

I have the following code:
DECLARE #x TABLE (item XML (document Galeries))
DECLARE #schemaname VARCHAR(100)
SET #schemaname = 'GaleriesSchem2'
INSERT into #x
SELECT '
<GaleriesSchem2>
<Image_1 OriginalName="Image">4814111.jpg</Image_1>
<Image_2 OriginalName="Image2">481411.jpg</Image_2>
</GaleriesSchem2>'
SELECT rref.value('.', 'varchar(MAX)') AS 'Value'
FROM #x
CROSS APPLY
item.nodes('//GaleriesSchem2/node()') AS Results(rref)
result:
1 | 4814111.jpg
2 | 481411.jpg
But I want to change the root element dynamically, for example:
item.nodes('//[local-name()=sql:variable("#schemaname")]/node()') AS Results(rref)
But this code doesn't work.
Use asterisk instead of double slash
DECLARE #x TABLE(item XML)
DECLARE #schemaname VARCHAR(100)
SET #schemaname = 'GaleriesSchem3'
INSERT into #x
SELECT '
<GaleriesSchem2>
<Image_1 OriginalName="Image">4814111.jpg</Image_1>
<Image_2 OriginalName="Image2">481411.jpg</Image_2>
</GaleriesSchem2>
<GaleriesSchem3>
<Image_1 OriginalName="Image">4814111_3.jpg</Image_1>
<Image_2 OriginalName="Image2">481411_3.jpg</Image_2>
</GaleriesSchem3>
'
SELECT rref.value('.', 'varchar(MAX)') AS 'Value'
FROM #x
CROSS APPLY
item.nodes('*[local-name()=sql:variable("#schemaname")]/node()') AS Results(rref)
See demo on SQLFiddle

saving the FOR XML AUTO results to variable in SQL

select #result=#input.query('*')
for xml raw,type
Above statement will generate following alert:
Msg 6819, Level 16, State 3, Line 2
The FOR XML clause is not allowed in a ASSIGNMENT statement.
For example
DECLARE #xml_var XML
SET #xml_var =
(
SELECT *,
(
SELECT *
FROM Orders
WHERE Orders.CustomerID=Customers.CustomerID
FOR XML AUTO, TYPE
)
FROM Customers WHERE CustomerID='ALFKI'
FOR XML AUTO, TYPE
)
refer to :
http://blogs.msdn.com/sqlprogrammability/articles/576095.aspx
DECLARE #RESULTS XML
SET #RESULTS = (SELECT * FROM Table_Name FOR XML AUTO)
SELECT #RESULTS
For those using SQL SERVER 2000, FOR XML is next to useless; You cannot assign the generated XML into a variable, insert into a table, etc. I had to do it manually when required, here's my sample:
SET NOCOUNT ON
create table #parcelData (
parcelID int
, [description] varchar(20)
)
--insert sample data
insert into #parcelData
select 1, 'apples' UNION
select 3, 'oranges' UNION
select 25, 'bananas' UNION
select 69, 'maracuja'
print '-- Example 1: FOR XML RAW --'
select parcelID as pID
from #parcelData
ORDER BY parcelID
FOR XML RAW
--> <row pID="17"/><row pID="25"/><row pID="26"/><row pID="333"/>
print '-- Example 2: Build XML Manually --'
declare #parcelRow varchar(50), #dummy int
, #xmlRowStr varchar(8000)
set #xmlRowStr = '' -- initialize.
DECLARE parcel_cursor CURSOR FOR
select DISTINCT '<row pID="' + cast(parcelID as varchar(10)) + '"/>', parcelID as parcelRow
from #parcelData
ORDER BY parcelID
OPEN parcel_cursor
FETCH NEXT FROM parcel_cursor
INTO #parcelRow, #dummy
WHILE ##FETCH_STATUS = 0 BEGIN
-- build the xml row by row.
set #xmlRowStr = #xmlRowStr + #parcelRow
-- Get next row
FETCH NEXT FROM parcel_cursor
INTO #parcelRow, #dummy
END
CLOSE parcel_cursor
DEALLOCATE parcel_cursor
--print #xmlRowStr
-- wrap a root element around
if #xmlRowStr != '' begin
set #xmlRowStr = '<ROOT>' + #xmlRowStr + '</ROOT>'
end
select #xmlRowStr as XmlOut
DROP TABLE #parcelData
SET NOCOUNT OFF