This should be simple but cannot get it to work after trying multiple suggestions from things I researched. I have some basic XML and just want to return the values from all the elements in seperate rows in a query result.
<Root>
<QueryRequest>
<ReturnedReuslts>
<Rows>
<Row>"1","Value 1"</Row>
<Row>"2","Value 2"</Row>
<Row>"3","Value 3"</Row>
</Rows>
</ReturnedReuslts>
</QueryRequest>
</Root>
I want it to return
Column 1 Column 2
-------- --------
1 Value 1
2 Value 2
3 Value 3
If I can't get it into two different columns, I'll settle for:
Column 1
----------------
"1","Value 1"
"2","Value 2"
"3","Value 3"
In SQL Server:
declare #strxml xml;
set #strxml = '<Root>
<QueryRequest>
<ReturnedReuslts>
<Rows>
<Row>"1","Value 1"</Row>
<Row>"2","Value 2"</Row>
<Row>"3","Value 3"</Row>
</Rows>
</ReturnedReuslts>
</QueryRequest>
</Root>'
select
substring(t1.col1, 1, charindex(',', t1.col1) - 1) Column1,
substring(t1.col1, charindex(',', t1.col1) + 1, len(t1.col1)) Column2
from
(select
col1 = replace(Node.Data.value('.', 'varchar(200)'), '"', '')
from
#strxml.nodes('/Root/QueryRequest/ReturnedReuslts/Rows/Row') Node(Data)) t1
Related
We have to find a query parsing XML to have a result like this one:
COL_ACTION N COL_NAME_I COL_VALUE_AFTER
---------- ----------- ---------------- -------------------
INS 1 N 1
INS 1 TST_ID 28
INS 1 TST_DATA data2
INS 2 N 2
INS 2 TST_ID 27
INS 2 TST_DATA data1
The value of column N depend on the value of the first "row" (COL_NAME_I = N) of the XML dataset
The XML contains:
DECLARE #XML XML =
N'
<DATASET>
<XML_INS>
<IROW xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<N>1</N>
<TST_ID>28</TST_ID>
<TST_DATA>data2</TST_DATA>
</IROW>
<IROW xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<N>2</N>
<TST_ID>27</TST_ID>
<TST_DATA>data1</TST_DATA>
</IROW>
</XML_INS>
</DATASET>
';
The query I was able to do is:
SELECT RIGHT(ca.value('local-name(.)','CHAR(7)'), 3) AS COL_ACTION,
x.value('(//N)[1]', 'int') AS N,
-- cn.value('./text()[1]','int') AS NI,
ci.value('local-name(.)','sysname') AS COL_NAME_I,
ci.value('./text()[1]','nvarchar(max)') AS COL_VALUE_AFTER
FROM #XML.nodes('.') AS T(x)
OUTER APPLY #XML.nodes('DATASET/*') AS TA(ca)
OUTER APPLY #XML.nodes('DATASET/XML_INS/IROW/N/*') AS TN(cn)
OUTER APPLY #XML.nodes('DATASET/XML_INS/IROW/*') AS TI(ci);
The problem remains on the "N" column that does no have the expected value:
COL_ACTION N COL_NAME_I COL_VALUE_AFTER
---------- ----------- ---------------- -------------------
INS 1 N 1
INS 1 TST_ID 28
INS 1 TST_DATA data2
INS 1 N 2
INS 1 TST_ID 27
INS 1 TST_DATA data1
I tryed different approach, as seen in SQL comment, but does not produce the good result...
You need each .nodes to refer to the previous, in order to only bring back its children. Otherwise you get every descendant node for the whole document.
SELECT RIGHT(action.value('local-name(.)','CHAR(7)'), 3) AS COL_ACTION,
irow.value('(N/text())[1]', 'int') AS N,
ci.value('local-name(.)','sysname') AS COL_NAME_I,
ci.value('text()[1]','nvarchar(max)') AS COL_VALUE_AFTER
FROM #XML.nodes('DATASET/*') AS x1(action)
OUTER APPLY x1.action.nodes('IROW') AS x2(irow)
OUTER APPLY x2.irow.nodes('*') AS TI(ci);
db<>fiddle
This should do it:
SELECT
irow.value('local-name(..)', 'NVARCHAR(100)') AS COL_ACTION,
irow.value('(./N)[1]', 'NVARCHAR(100)') AS N,
child.value('local-name(.)', 'NVARCHAR(100)') AS COL_NAME_I,
child.value('.', 'NVARCHAR(100)') AS COL_VALUE_AFTER
FROM #XML.nodes('/DATASET/*/IROW') AS n1(irow)
CROSS APPLY irow.nodes('./*') AS n2(child)
i am a new contributer so sorry if i got something wrong.
I used this approach on my work : Link
My sample working code :
CREATE TABLE #FieldPermissionsTable
(
TE_ID VARCHAR(MAX),
Value VARCHAR(MAX),
Value2 VARCHAR(MAX),
NAVI_USER VARCHAR(MAX)
)
--SET #FieldPermissionAccessXML = '<Row_ID><Elements ID="1" Value="1" Value2="NULLnROLLA" Navi_User="testuser" /><Elements ID="3" Value="tespit" Value2="NULLnROLLA" Navi_User="testuser" /><Elements ID="6" Value="aciklama" Value2="NULLnROLLA" Navi_User="testuser" /></Row_ID>'
-- SELECT #FieldPermissionAccessXML = [dbo].[to_xml_replace] (#FieldPermissionAccessXML)
EXEC sp_xml_preparedocument #XmlHandle output,#FieldPermissionAccessXML
--'<FieldPermissions>
--<FieldPermission FieldName="" RoleID="1" Access="1" />
--<FieldPermission FieldName="" RoleID="2" Access="1" />'
--select * from JMP_FieldPermissions
INSERT INTO #FieldPermissionsTable
SELECT *--ID,Value, Value2, Navi_User
FROM OPENXML (#XmlHandle, './Row_ID/Elements')
WITH (TE_ID VARCHAR(MAX) '#ID',
Value VARCHAR(MAX) '#Value',
Value2 VARCHAR(MAX) '#Value2',
NAVI_USER VARCHAR(MAX) '#Navi_User'
)
I want to convert my found data to a single column
My data is
Id
------
3
4
5
that record I want to this format
id
=======
3,4,5
Try,
SELECT STUFF( (SELECT ',' + Id
FROM My_Table
ORDER BY Id
FOR XML PATH('')),
1, 1, '')
Original_Post_Here
Another way
DECLARE #str VARCHAR(1000)
SELECT #str = coalesce(#str + ',', '') + a.[Your Column]
FROM (
SELECT DISTINCT [Your Column]
FROM [your Table]
) a
SELECT #str
what is simple way to produce output concatenated into single column for all Parameter values in sample below, this xml doesn't have an ns in it and I'm using SQL Server 2012.
I try to get this output, below snippet with xml sample produce 3 columns, and I'd like to make 1.
100 | Param1
,Param22
,Param3322
XML & code:
DECLARE #xml XML = '<Parameters>
<Parameter>
<Name>Param1</Name>
</Parameter>
<Parameter>
<Name>Param22</Name>
</Parameter>
<Parameter>
<Name>Param3322</Name>
</Parameter> </Parameters> '
SELECT 100 id
,#XML xmlinfo
INTO #t -- drop table #t -- select * from #t
DECLARE #xml XML = (
SELECT xmlinfo
FROM #t
)
SELECT (
SELECT ID
FROM #t
) AS ID
,X.STockData.query('Name[1]').value('.', 'Varchar(10)') AS 'Parameter'
---CONCAT(X.STockData.query('Name[1]').value('.','Varchar(10)'),X.STockData.query('Name[2]').value('.','Varchar(10)')) AS 'Parameter'
FROM #xml.nodes('Parameters/Parameter') AS X(StockData)
You can use XQuery for loop to construct comma-separated value from XML field, for example :
SELECT
t.ID as ID
, CAST(t.xmlinfo.query('
for $p in Parameters/Parameter
return
if ($p is (Parameters/Parameter[last()])[1])
then string($p/Name[1])
else concat($p/Name[1], ", ")
')
AS VARCHAR(MAX)
) as Parameter
FROM MyTable as t
Sqlfiddle Demo
The XQuery above simply loop through Parameter elements, and return Name child element if current Parameter is the last Parameter, otherwise return Name concatenated with comma.
SELECT (
SELECT ID
FROM #t
) AS ID
,X.STockData.query('Name[1]').value('.', 'Varchar(10)')
+ ', ' + X.STockData.query('Name[2]').value('.', 'Varchar(10)')
+ ', ' + X.STockData.query('Name[3]').value('.', 'Varchar(10)')
as parameter
FROM #xml.nodes('Parameters/Parameter') AS X(StockData)
Try this
I am trying to produce the following XML as a column of a table:
<root>
<Address1>
<Addressline1>Test Road</Addressline1>
<Addressline2>Test Street</Addressline2>
<Addressline3>Test Town</Addressline3>
<Addressline4>Test State</Addressline4>
<Postcode>Test Postcode</Postcode>
</Address1>
<Address2>
<Addressline1>Test Road</Addressline1>
<Addressline2>Test Street</Addressline2>
<Addressline3>Test Town</Addressline3>
<Addressline4>Test State</Addressline4>
<Postcode>Test Postcode</Postcode>
</Address2>
</root>
I am almost there with the following SQL:
select (1Addressline1,
1Addressline2,
1Addressline3,
1Addressline4,
1Postcode for xml path('Address'), root('Addresses')) AS Address1,
(2Addressline1,
2Addressline2,
2Addressline3,
2Addressline4,
2Postcode for xml path('Address'), root('Addresses')) AS Address2,
ColumnA
ColumnB
ColumnC
From Addresses
Which produces the following XML:
<root>
<Address1>
<Addressline1>Test Road</Addressline1>
<Addressline2>Test Street</Addressline2>
<Addressline3>Test Town</Addressline3>
<Addressline4>Test State</Addressline4>
<Postcode>Test Postcode</Postcode>
</Address1>
</root>,
<root>
<Address2>
<Addressline1>Test Road</Addressline1>
<Addressline2>Test Street</Addressline2>
<Addressline3>Test Town</Addressline3>
<Addressline4>Test State</Addressline4>
<Postcode>Test Postcode</Postcode>
</Address2>
</root>,
ColumnA,
ColumnB,
ColumnC
It is not correct at is produces two separate XML columns. I now need to combine Address1 and Address 2 under the root node as above but cannot work out or find the correct syntax.
EDIT: As suggested I have modified my code to this which is giving a number of syntax errors:
SELECT ColumnA,
ColumnB,
ColumnC,
(
select
(
(
select RTRIM(Address1Line1),
RTRIM(Address1Line2),
RTRIM(Address1Line3),
RTRIM(Address1Line4),
RTRIM(Address1Line5)
for xml path('Address'), type
),
(
select RTRIM(Address2Line1),
RTRIM(Address2Line2),
RTRIM(Address2Line3),
RTRIM(Address2Line4),
RTRIM(Address2Line5)
for xml path('Address'), type
)
) FOR XML PATH(''), root('Addresses'),type
) AS Addresses
FROM TableA
DECLARE #Addresses TABLE
(AddressNumber INT, Addressline1 VARCHAR(50),Addressline2 VARCHAR(50)
,Addressline3 VARCHAR(50),Addressline4 VARCHAR(50),PostCode VARCHAR(50))
INSERT INTO #Addresses VALUES
(1,'Add 1 Addressline1', 'Add 1 Addressline2', 'Add 1 Addressline3', 'Add 1 Addressline4', 'ABCD132'),
(2,'Add 2 Addressline1', 'Add 2 Addressline2', 'Add 2 Addressline3', 'Add 2 Addressline4', 'JKLM132'),
(3,'Add 3 Addressline1', 'Add 3 Addressline2', 'Add 3 Addressline3', 'Add 3 Addressline4', 'RTPZ132'),
(4,'Add 4 Addressline1', 'Add 4 Addressline2', 'Add 4 Addressline3', 'Add 4 Addressline4', 'XMLO132')
select AddressNumber [#AddressID]
,Addressline1
,Addressline2
,Addressline3
,Addressline4
,PostCode
FROM #Addresses
for xml PATH('Address'),Elements , root('PatientAddress')
Result Set
<PatientAddress>
<Address AddressID="1">
<Addressline1>Add 1 Addressline1</Addressline1>
<Addressline2>Add 1 Addressline2</Addressline2>
<Addressline3>Add 1 Addressline3</Addressline3>
<Addressline4>Add 1 Addressline4</Addressline4>
<PostCode>ABCD132</PostCode>
</Address>
<Address AddressID="2">
<Addressline1>Add 2 Addressline1</Addressline1>
<Addressline2>Add 2 Addressline2</Addressline2>
<Addressline3>Add 2 Addressline3</Addressline3>
<Addressline4>Add 2 Addressline4</Addressline4>
<PostCode>JKLM132</PostCode>
</Address>
<Address AddressID="3">
<Addressline1>Add 3 Addressline1</Addressline1>
<Addressline2>Add 3 Addressline2</Addressline2>
<Addressline3>Add 3 Addressline3</Addressline3>
<Addressline4>Add 3 Addressline4</Addressline4>
<PostCode>RTPZ132</PostCode>
</Address>
<Address AddressID="4">
<Addressline1>Add 4 Addressline1</Addressline1>
<Addressline2>Add 4 Addressline2</Addressline2>
<Addressline3>Add 4 Addressline3</Addressline3>
<Addressline4>Add 4 Addressline4</Addressline4>
<PostCode>XMLO132</PostCode>
</Address>
</PatientAddress>
just replace the literals with the name of the columns in your table:
select
(SELECT '1' addressline1,'2' addressline2, '3' addressline3, '4' addressline4, 'PC' postcode for xml path('Address1'), type ),
(SELECT '21' addressline1,'22' addressline2, '23' addressline3, '24' addressline4, '2PC' postcode for xml path('Address2'), type )
FOR XML PATH(''), root('PatientAddress'),type
declare #x xml
set #x = '<Root>
<row id="1"><name>Larry</name><oflw>some text</oflw></row>
<row id = "2"><name>moe</name></row>
<row id = "3"/>
</Root>'
select T.c.query(..) as result from #x.nodes('/Root/row') T(C)
select T.c.query(..) as result from #x.nodes('/Root/row') T(C)
I am getting following error.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ')'.
could any one help me correcting the error. I am new to sql .
It should one this:
select T.c.query('..') as result from #x.nodes('/Root/row') T(C)
or maybe
select T.c.query('.') as result from #x.nodes('/Root/row') T(C)
The path parameter to the query method should be a string
Not sure what you're trying to extract from your XML - but try this query - it will "take apart" all the bits of information stored in the XML and show them as separate values:
declare #x xml
set #x = '<Root>
<row id="1"><name>Larry</name><oflw>some text</oflw></row>
<row id="2"><name>moe</name></row>
<row id="3"/>
</Root>'
select
T.c.value('#id', 'int') as 'ID',
T.c.value('(name)[1]', 'varchar(25)') as result,
T.c.value('(oflw)[1]', 'varchar(25)') as 'OFlw'
from #x.nodes('/Root/row') T(C)
Output:
ID result OFlw
1 Larry some text
2 moe NULL
3 NULL NULL