I have a table in containing name-value pairs. I want to serialized the name value pairs into an xml structure with a single element for each name-value-pair with the [Name] column as the xml element name, and the [Value] column as the content of the XML node.
e.g. given the following sample data...
;with nvp (Name, Value) as
(
select 'Food', 'Tacos' union all
select 'Height', '5''9"' union all
select 'Value', '3.141'
)
select *
from nvp
I want an xml chunk that looks like this:
<root>
<Food>Tacos</Food>
<Height>5'9"</Height>
<Value>3.141</Value>
</root>
When I tried FOR XML PATH I get something like below, which is NOT what I want.
<root>
<Name>Food</Name>
<Value>Tacos</Value>
</root>
<root>
<Name>Height</Name>
<Value>5'9"</Value>
</root>
<root>
<Name>Value</Name>
<Value>3.141</Value>
</root>
Anyone know how to do this?
Do a transpose of rows to columns before convert into XML.
Also mention the Root name in Xml path()
;WITH nvp (NAME, Valued)
AS (SELECT 'Food', 'Tacos'
UNION ALL
SELECT 'Height', '5''9"'
UNION ALL
SELECT 'Value', '3.141')
SELECT *
FROM nvp
PIVOT (Max(valued)
FOR NAME IN ([Food],
[Height],
[Value])) pv
FOR xml path('root')
Result:
<root>
<Food>Tacos</Food>
<Height>5'9"</Height>
<Value>3.141</Value>
</root>
Related
I can't receive XML in this format:
<ROOT>
<Test ColA="A">B</Test>
</ROOT>
This what I have:
select 'A' as ColumnA, 'B' as ColumnB into _Atest
select ColumnA as [Test/#A]
from _Atest
for XML PATH (''), root ('ROOT')
And output are:
<ROOT>
<Test A="A" />
</ROOT>
How I can receive:
<ROOT>
<Test ColA="A">B</Test>
</ROOT>
"A" - value from ColumnA
B - value from ColumnB
Please try the following.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ColumnA CHAR(1), ColumnB CHAR(1));
INSERT INTO #tbl (ColumnA, ColumnB) VALUES
('A', 'B');
-- DDL and sample data population, end
SELECT ColumnA AS [Test/#ColA]
, ColumnB AS [Test]
FROM #tbl
FOR XML PATH(''), TYPE, ROOT('ROOT');
Output
<ROOT>
<Test ColA="A">B</Test>
</ROOT>
I wish to generate xml data in the following format - animal value must be tag name
<pets>
<dog>
<name>spot</name>
</dog>
<cat>
<name>tom</name>
</cat>
</pets>
I can write some dynamic sql but if there is a better way????
;with cte(animal,name)
as
(
select 'dog','spot' union
select 'cat','tom'
)
select
animal
,name
from cte
for xml path(animal),root('pets')
Use the next code:-
SELECT (
SELECT 'spot' AS name
FOR
XML PATH('dog'),
TYPE
),
( SELECT 'tom' AS name
FOR
XML PATH('cat'),
TYPE
)
FOR XML PATH(''),
ROOT('Pets')
GO
Result:-
<Pets>
<dog>
<name>spot</name>
</dog>
<cat>
<name>tom</name>
</cat>
</Pets>
This is my sample XML:
<root>
<element>
<subelement>
<value code="code1">value1</value>
<value code="code2">value2</value>
</subelement>
</element>
</root>
And this is my test query:
DECLARE #tempTable TABLE (
ValueCode nvarchar(MAX),
Value nvarchar(MAX)
)
DECLARE #xml XML
select #xml = cast(c1 as xml) from OPENROWSET (BULK 'C:\test.xml', SINGLE_BLOB) as T1(c1)
INSERT INTO #tempTable
SELECT
Tbl.Col.value('subelement[1]/#code', 'NVARCHAR(MAX)'),
Tbl.Col.value('subelement[1]', 'NVARCHAR(MAX)')
FROM #xml.nodes('//element') Tbl(Col)
SELECT * FROM #tempTable
The query, when executed, gives out a row with the ValueCode column containing NULL and the Value column containing 'value1value2'. What I would like to get would be the attributes and values concatenated with a separator. For example, I need ValueCode to contain 'code1; code2' and Value to contain 'value 1; value2'. How can I achieve that?
you can use xuery if you want concatenated strings:
SELECT
Tbl.Col.query('for $i in value return concat($i/text()[1], ";")').value('.', 'nvarchar(max)'),
Tbl.Col.query('for $i in value return concat($i/#code, ";")').value('.', 'nvarchar(max)')
FROM #xml.nodes('root/element/subelement') Tbl(Col);
if you want your values into rows:
SELECT
Tbl.Col.value('.', 'nvarchar(max)'),
Tbl.Col.value('#code', 'nvarchar(max)')
FROM #xml.nodes('root/element/subelement/value') Tbl(Col);
sql fiddle demo
I would like to query multiple tables from SQL Server 2005 and create a single XML document and do this in a stored procedure.
I know that I can query multiple tables within a stored procedure and get a DataSet in my .NET application that can be easily saved as XML. However, I'm trying to do something similar within the context of a stored procedure.
Essentially I want to do something like this:
declare #x xml
select #x = x.result
from (select y.* from tabley y for xml path('y')
union
select a.* from tablea a for xml path('aa')
) as x
select #x
If you want them just one after the other, you can try something like this:
SELECT
(SELECT y.* FROM dbo.TableY FOR XML PATH('y'), TYPE) AS 'YElements',
(SELECT a.* FROM dbo.TableA FOR XML PATH('aa'), TYPE) AS 'AElements'
FOR XML PATH(''), ROOT('root')
That return an XML something like:
<root>
<YElements>
<Y>
....
</Y>
<Y>
....
</Y>
......
</YElements>
<AElements>
<A>
....
</A>
<A>
....
</A>
......
</AElements>
</root>
SELECT -- Root Starts
(SELECT '1' AS ErrorCode FOR XML PATH(''), TYPE) AS 'Results', -- Level 1 Starts
(select -- Level 2 Starts
(select '1' CustomerID, -- Level 2 Detail Starts
'John' CustomerName,
'Doe' CustomerLastname,
'Y' Active
for xml path('Customers'), type) AS 'Customer' -- Level 2 Detail Ends
for xml path(''), TYPE) AS 'Response' -- Level 2 Ends
FOR XML PATH('') -- Level 1 Ends
,ROOT('BaseXML') -- Root Ends
Convert Table XML in sql server.
Declare #RESULTXML XML
Declare #SMS_REGISTER TABLE([id] VARCHAR(30),[status] VARCHAR(30))
Declare #EMAIL_REGISTER TABLE([id] VARCHAR(30),[status] VARCHAR(30))
Declare #ODP_REGISTER TABLE([id] VARCHAR(30),[status] VARCHAR(30))
Select #RESULTXML =(
SELECT (SELECT * FROM #SMS_REGISTER FOR XML PATH('sms'), TYPE) AS 'smss',
(SELECT * FROM #EMAIL_REGISTER FOR XML PATH('email'), TYPE) AS 'emails',
(SELECT * FROM #ODP_REGISTER FOR XML PATH('odp'), TYPE) AS 'odps'
FOR XML PATH('subroot'), ROOT('root') )
Return XML Like this
<root>
<subroot>
<smss>
<sms>
<id>NT0000000020</id>
<status>registered</status>
</sms>
<sms>
<id>NT0000000021</id>
<status>registered</status>
</sms>
<sms>
<id>NT0000000022</id>
<status>registered</status>
</sms>
<sms>
<id>NT0000000023</id>
<status>registered</status>
</sms>
</smss>
<emails>
<email>
<id>NT0000000024</id>
<status>registered</status>
</email>
<email>
<id>NT0000000025</id>
<status>registered</status>
</email>
</emails>
</subroot>
</root>
I'm rather experienced with SQL server "select for XML path" queries but now i run into a strange problem.
The following query works fine:
select
(
select
'Keyfield1' as "#Name",
t1.Keyfield1 as "Value"
from MyTable t1
where
t1.KeyField1= t2.KeyField1 and
t1.KeyField2= t2.KeyField2
for xml path('Field'),type, elements
) as 'Key'
from MyTable t2
for XML path('Path') , elements XSINIL, root('Root')
This will result (for a dummy dataset) in this XML:
<Root>
<Path>
<Key Name="KeyField1">
<Value>DummyValue1</Value>
</Key>
</Path>
</Root>
In my result of this (part of a bigger) statement i need the 2nd keyfield too:
<Root>
<Path>
<Key Name="KeyField1">
<Value>DummyValue1</Value>
</Key>
<Key Name="KeyField2">
<Value>DummyValue2</Value>
</Key>
</Path>
</Root>
So i changed my (sub)query with a union-select to:
select
(
select
'Keyfield1' as "#Name",
t1.Keyfield1 as "Value"
union all
select
'Keyfield2' as "#Name",
t1.Keyfield2 as "Value"
from MyTable t1
where
t1.KeyField1= t2.KeyField1 and
t1.KeyField2= t2.KeyField2
for xml path('Field'),type, elements
) as 'Key'
from MyTable t2
for XML path('Path') , elements XSINIL, root('Root')
But now i get the error "Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
I know it is possible to have multiple records in a subquery with for XML path witch results in multiple elements. But i don't understand why this can't be done with a union.
Can someone put me in the right direction how to accomplisch the XML with the 2 keyfields in my (sub)query?
Thanx you very much.
The problem with your subselect is that the first part isn't referring to any table at all (no FROM-clause).
This listing gives me the output you requested:
declare #mytable table (
keyfield1 nvarchar(20),
keyfield2 nvarchar(20)
)
insert into #mytable values ('Dummyvalue1', 'Dummyvalue2')
select * from #mytable
select
(
select
'Keyfield1' as "#Name",
t1.Keyfield1 as "Value"
from #mytable t1
where
t1.KeyField1= t2.KeyField1 and
t1.KeyField2= t2.KeyField2
for xml path('Field'),type, elements
) as 'Key'
from #mytable t2
for XML path('Path') , elements XSINIL, root('Root')
select
(
select * from (
select
'Keyfield1' as "#Name",
t1.Keyfield1 as "Value"
from #MyTable t1
where
t1.KeyField1= t2.KeyField1
union all
select
'Keyfield2' as "#Name",
t3.Keyfield2 as "Value"
from #MyTable t3
where
t3.KeyField2= t2.KeyField2) a
for xml path('Field'),type, elements
) as 'Key'
from #MyTable t2
for XML path('Path') , elements XSINIL, root('Root')
Here is a simplified example, but does this get you what you need?
select
(
select
'Keyfield1' as "#Name",
'Blah' as "Value"
for xml path('Key'),type, elements
),
(
select
'Keyfield2' as "#Name",
'Blah' as "Value"
for xml path('Key'),type, elements
)
for XML path('Path') , elements XSINIL, root('Root')