SQL Server stored procedure - Table to XML object - sql-server

I need to write a stored procedure that can create the following output from values from a SQL Server table:
<object>
<ValueList>
<Value value="1" text="Name" enabled="1" alias="Alias" />
<Value value="2" text="Name" enabled="1" alias="Alias" />
<Value value="3" ....
...
...
</ValueList>
</object>
I have tried to convert my table into XML using this procedure:
select TXT as [text]
from lit_geography
for XML raw ('value'), root('object')
Then I get the following
<object>
<value text="Midler tidig havn" />
<value text="Færgehavnsvej" />
<value text="Sydhavnsvej" />
<value text="Ø-Pladsen" />
<value text="Havnepladsen" />
</object>
TODO:
I am missing the parent node Valuelist
I need to append the following:
value="1", value="2" etc etc counting up for each value
enabled="1"
alias=""

For the incremental value, you can use Row_Number()
Example
Select (
Select [value] = row_number() over (Order by (select null))
,[text] = txt
,[enabled] = 1
,[alias] = 'Alias'
From lit_geography
For XML Raw('Value'),type
)
For XML Path('ValueList'),Root('object')
Returns
<object>
<ValueList>
<Value value="1" text="Midler tidig havn" enabled="1" alias="Alias" />
<Value value="2" text="Færgehavnsvej" enabled="1" alias="Alias" />
<Value value="3" text="Sydhavnsvej" enabled="1" alias="Alias" />
<Value value="4" text="Ø-Pladsen" enabled="1" alias="Alias" />
<Value value="5" text="Havnepladsen" enabled="1" alias="Alias" />
</ValueList>
</object>
EDIT - Requested UPDATE
Update lit_formfield set [Values] = (
Select (
Select [value] = row_number() over (Order by (select null))
,[text] = txt
,[enabled] = 1
,[alias] = 'Alias'
From lit_geography
For XML Raw('Value'),type
)
For XML Path('ValueList'),Root('object')
)
Where Label = 'listbox'

Related

Updating multiple XML columns using single update in SQL Server

I would like to update a table_A with new values for (AcresDist1, txtAcresDist1, txtAcresDist1Total) XML columns from a second table_B.
The column P_XML is of XML type. I know how to update a single column at once, but I would like to know how to update multiple columns in the XML using a single update statement. Thanks
SQL code:
UPDATE S
SET
P_XML.modify( N'replace value of (/FormValue/f1152_F1/Field[(id/text())[1]="AcresDist1"]/value/text())[1] with sql:column(''T.AcresDist1'')' )
, P_XML.modify( N'replace value of (/FormValue/f1152_F1/Field[(id/text())[1]="txtAcresDist1"]/value/text())[1] with sql:column(''T.txtAcresDist'')' )
, P_XML.modify( N'replace value of (/FormValue/f1152_F1/Field[(id/text())[1]="txtAcresDist1Total"]/value/text())[1] with sql:column(''T.txtAcresDist1Total'')' )
FROM
Table_A AS S
INNER JOIN
Table_B AS T ON s.P_NO = t.P_Number
AND s.FAC_RID = t.Fac_RID;
Here is the sample xml as requested. Thank you.
<FormValue>
<f1152>
<field>
<id>f1152_MainForm</id>
<value />
<tag />
<visible>true</visible>
<history>|09/28/2017 10:50:26 AM||</history>
<description />
<comment />
</field>
<field>
<id>txt_rdoCoverage</id>
<value>Development</value>
<tag />
<visible>false</visible>
<history>|09/28/2017 10:50:26 AM||</history>
<description />
<comment />
</field>
</f1152>
<f1152_F1>
<field>
<id>txtAcresDist1</id>
<value>1.2</value>
<tag />
<visible>false</visible>
<history>|09/28/2017 3:08:14 AM||</history>
<description />
<comment />
</field>
<field>
<id>txtAcresDist1Total</id>
<value>200</value>
<tag />
<visible>false</visible>
<history>|09/28/2017 3:08:14 AM||</history>
<description />
<comment />
</field>
</f1152_F1>

Parsing XML in T-SQL - ABS data

I'm after some assistance parsing an xml file provided by the Australian Bureau of Statistics. I've read over everything I can find here and online, and am not having much luck reading this data.
This is a sample of the XML:
<?xml version='1.0' encoding='UTF-8'?>
<message:MessageGroup xmlns:message="http://www.w3.org/2001/XMLSchema" xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic" xmlns:common="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/common" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic http://www.sdmx.org/docs/2_0/SDMXGenericData.xsd http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message http://www.sdmx.org/docs/2_0/SDMXMessage.xsd">
<Header xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message">
<ID>none</ID>
<Test>false</Test>
<Truncated>false</Truncated>
<Prepared>2018-02-14T22:41:03</Prepared>
<Sender id="ABS">
<Name xml:lang="en">Australian Bureau of Statistics</Name>
<Name xml:lang="fr">Australian Bureau of Statistics</Name>
</Sender>
</Header>
<DataSet keyFamilyURI="http://stat.data.abs.gov.au/restsdmx/sdmx.ashx/GetKeyFamily/RES_PROP_INDEX">
<KeyFamilyRef>RES_PROP_INDEX</KeyFamilyRef>
<Series>
<SeriesKey>
<Value concept="MEASURE" value="1" />
<Value concept="PROP_TYPE" value="3" />
<Value concept="ASGS_2011" value="3GBRI" />
<Value concept="FREQUENCY" value="Q" />
</SeriesKey>
<Attributes>
<Value concept="TIME_FORMAT" value="P3M" />
</Attributes>
<Obs>
<Time>2015-Q1</Time>
<ObsValue value="112.7" />
</Obs>
<Obs>
<Time>2015-Q2</Time>
<ObsValue value="113.7" />
</Obs>
</Series>
<Series>
<SeriesKey>
<Value concept="MEASURE" value="1" />
<Value concept="PROP_TYPE" value="3" />
<Value concept="ASGS_2011" value="5GPER" />
<Value concept="FREQUENCY" value="Q" />
</SeriesKey>
<Attributes>
<Value concept="TIME_FORMAT" value="P3M" />
</Attributes>
<Obs>
<Time>2015-Q1</Time>
<ObsValue value="114.4" />
</Obs>
<Obs>
<Time>2015-Q2</Time>
<ObsValue value="113.4" />
</Obs>
</Series>
<Annotations>
<common:Annotation>
<common:AnnotationTitle>Statistical usage warning</common:AnnotationTitle>
<common:AnnotationText>ABS.Stat beta is continuing to be developed. Data will be updated as soon as possible following its 11:30 am release on the ABS website.</common:AnnotationText>
</common:Annotation>
</Annotations>
</DataSet>
</message:MessageGroup>
The result set should return 3 values:
SeriesKey Value where Concept = 'ASGS_2011'
Obs "Time" Value
Obs "Obsvalue" Value
e.g the first record would return a row like:
3GBRI | 2015-Q1 | 112.7
This sample would return 4 rows of data like this.
I've tried inserting the XML into an XML variable or a column in a DB with an XML datatype, and then using SQL's XML functionality, but I'm an absolute novice at this and am having trouble with the correct coding/approach.
Any advice or sample code would be greatly appreciated.
I'd suggest do get rid of the <?xml blah ?> declaration. This is only useful when you store an XML to a file. Within SQL-Server any XML's encoding is fixed to unicode / UCS-2. This can lead to encoding problems...
There are namespaces involved...
DECLARE #xml XML=
'<?xml version=''1.0'' encoding=''UTF-8''?>
<message:MessageGroup xmlns:message="http://www.w3.org/2001/XMLSchema" xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic" xmlns:common="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/common" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic http://www.sdmx.org/docs/2_0/SDMXGenericData.xsd http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message http://www.sdmx.org/docs/2_0/SDMXMessage.xsd">
<Header xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message">
<ID>none</ID>
<Test>false</Test>
<Truncated>false</Truncated>
<Prepared>2018-02-14T22:41:03</Prepared>
<Sender id="ABS">
<Name xml:lang="en">Australian Bureau of Statistics</Name>
<Name xml:lang="fr">Australian Bureau of Statistics</Name>
</Sender>
</Header>
<DataSet keyFamilyURI="http://stat.data.abs.gov.au/restsdmx/sdmx.ashx/GetKeyFamily/RES_PROP_INDEX">
<KeyFamilyRef>RES_PROP_INDEX</KeyFamilyRef>
<Series>
<SeriesKey>
<Value concept="MEASURE" value="1" />
<Value concept="PROP_TYPE" value="3" />
<Value concept="ASGS_2011" value="3GBRI" />
<Value concept="FREQUENCY" value="Q" />
</SeriesKey>
<Attributes>
<Value concept="TIME_FORMAT" value="P3M" />
</Attributes>
<Obs>
<Time>2015-Q1</Time>
<ObsValue value="112.7" />
</Obs>
<Obs>
<Time>2015-Q2</Time>
<ObsValue value="113.7" />
</Obs>
</Series>
<Series>
<SeriesKey>
<Value concept="MEASURE" value="1" />
<Value concept="PROP_TYPE" value="3" />
<Value concept="ASGS_2011" value="5GPER" />
<Value concept="FREQUENCY" value="Q" />
</SeriesKey>
<Attributes>
<Value concept="TIME_FORMAT" value="P3M" />
</Attributes>
<Obs>
<Time>2015-Q1</Time>
<ObsValue value="114.4" />
</Obs>
<Obs>
<Time>2015-Q2</Time>
<ObsValue value="113.4" />
</Obs>
</Series>
<Annotations>
<common:Annotation>
<common:AnnotationTitle>Statistical usage warning</common:AnnotationTitle>
<common:AnnotationText>ABS.Stat beta is continuing to be developed. Data will be updated as soon as possible following its 11:30 am release on the ABS website.</common:AnnotationText>
</common:Annotation>
</Annotations>
</DataSet>
</message:MessageGroup>';
--The query will declare the needed namespaces and then use .nodes() to get the <Series> and a second call to .nodes() to get the nested <Obs>:
WITH XMLNAMESPACES(DEFAULT 'http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic'
,'http://www.w3.org/2001/XMLSchema' AS message)
SELECT ser.value(N'(SeriesKey/Value[#concept="ASGS_2011"]/#value)[1]',N'nvarchar(max)') AS Concept
,obs.value(N'(Time/text())[1]',N'nvarchar(max)') AS [Time]
,obs.value(N'(ObsValue/#value)[1]',N'decimal(10,4)') AS ObsValue
FROM #xml.nodes(N'/message:MessageGroup/DataSet/Series') AS A(ser)
OUTER APPLY A.ser.nodes(N'Obs') AS B(obs);
The result
Concept Time ObsValue
3GBRI 2015-Q1 112.7000
3GBRI 2015-Q2 113.7000
5GPER 2015-Q1 114.4000
5GPER 2015-Q2 113.4000

Convert XML to SQL Server 2008R2 table [duplicate]

This question already has answers here:
Import 'xml' into Sql Server
(5 answers)
Closed 5 years ago.
I want to import below XML file into SQL table. (SQL Server 2008R2)
<table>
<id>{72cbb5ab-dbb3-4de7-9010-5dd1192a1851}</id>
<rows>
<row>
<columns>
<column name="itemcode" value="0984-22-301" type="System.String" />
<column name="date" value="08-November-2017" type="System.DateTime" />
<column name="amount" value="10" type="System.Decimal" />
<column name="DefaultKey" value="1" type="System.Int32" />
</columns>
</row>
<row>
<columns>
<column name="itemcode" value="0984-33-101" type="System.String" />
<column name="date" value="08-November-2017" type="System.DateTime" />
<column name="amount" value="11" type="System.Decimal" />
<column name="DefaultKey" value="2" type="System.Int32" />
</columns>
</row>
</rows>
<key>DefaultKey</key>
<total>0</total>
<data />
<parameters />
</table>
It should look like a sql table with columns id, itemcode, date and amount.
How should my query look like?
Solved the question.
declare #xmltable table (data xml)
insert into #xmltable (data)
select DATA from [MyData]..myxml
SELECT
LineId = c.value('id[1]', 'nvarchar(max)'),
ColumnItemCode = l.value('(columns/column[#name="itemcode"]/#value)[1]', 'varchar(20)'),
ColumnDate = l.value('(columns/column[#name="date"]/#value)[1]', 'varchar(20)'),
ColumnAmount = l.value('(columns/column[#name="amount"]/#value)[1]', 'varchar(20)')
FROM
#xmltable x
CROSS APPLY data.nodes('table') t(c)
CROSS APPLY data.nodes('table/rows/row') b(l)
This resulted in:
LineId ColumnItemCode ColumnDate ColumnAmount
{72cbb5ab-dbb3-4de7-9010-5dd1192a1851} 0984-22-301 08-November-2017 10
{72cbb5ab-dbb3-4de7-9010-5dd1192a1851} 0984-33-101 08-November-2017 11
Thanks for your help.

Guide or any tool to convert FetchXML to SQL Query

I have below FetchXML query used to create report in Business Intelligent Development Studio.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="incident">
<attribute name="ticketnumber" />
<attribute name="createdon" />
<attribute name="statuscode" />
<attribute name="incidentid" />
<attribute name="caseorigincode" />
<attribute name="new_statussla" />
<attribute name="ownerid" />
<attribute name="new_caseaging" />
<attribute name="casetypecode" />
<order attribute="ticketnumber" descending="false" />
<filter type="and">
<condition attribute="createdon" operator="on-or-after" value="#Startdate" />
<condition attribute="createdon" operator="on-or-before" value="#Enddate" />
<condition attribute="caseorigincode" operator="ne" value="3" />
</filter>
<link-entity name="systemuser" from="systemuserid" to="owninguser" visible="false" link-type="outer" alias="a_cf39b8fda77b421483a1af5e511c39ca">
<attribute name="new_region" />
<attribute name="businessunitid" />
</link-entity>
</entity>
</fetch>
I do converting this query to SQL query like below.
SELECT a.ticketnumber, a.createdon, a.statuscode,
a.incidentid, a.caseorigincode, a.new_statussla,
a.ownerid, a.new_caseaging, a.casetypecode,
b.new_region, b.businessunitid
FROM FilteredIncident a, FilteredSystemUser b
WHERE a.ownerid = b.systemuserid
AND createdon >= #StartDate
AND creaedon <= #EndDate
AND caseorigincode != '3'
My Question, is my SQL Query correct ? Eventhough I can execute it.
Well out of need I just created this. FetchXML to SQL Convertor free on GitHub!
A work in progress, but will give a usable output. Do Try! https://github.com/abtevrythng/FetchXML-to-SQL
here is the generated output for your fetchXML:
SELECT incident.ticketnumber, incident.createdon, incident.statuscode, incident.incidentid, incident.caseorigincode, incident.new_statussla, incident.ownerid, incident.new_caseaging, incident.casetypecode, systemuser.new_region, systemuser.businessunitid
FROM incident
LEFT OUTER JOIN systemuser ON incident.systemuserid = systemuser.owninguser
WHERE incident.createdon TBD '#Startdate' AND incident.createdon TBD '#Enddate' AND incident.caseorigincode != '3'

xml.value() method in SQL Server (Getting a value inside an XML query)

I have an XML Query like this:
<ChangeSet xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Change DateTime="2011-12-02T09:01:58.3615661-08:00" UserId="3123">
<Table ChangeType="Insert" Name="EVNT_LN_AFF">
<Keys>
<Key FieldName="DIR_CD" Value="NB" />
<Key FieldName="LN_ID" Value="A" />
<Key FieldName="EVNT_ID" Value="10T000289" />
</Keys>
<ChangedFields>
<Field FieldName="DIR_CD" Previous="" Current="NB" />
<Field FieldName="LN_ID" Previous="" Current="A" />
<Field FieldName="EVNT_ID" Previous="" Current="10T000289" />
<Field FieldName="UD_DTTM" Previous="" Current="12/2/2011 9:01:59 AM" />
<Field FieldName="UD_USER_ID" Previous="" Current="3123" />
</ChangedFields>
</Table>
(The query goes on)
Now I want to use a statement like this:
SELECT TOP 1000 [CHG_LOG_ID]
, [EVNT_ID]
, [DATA_XML_TXT]
, [UD_DTTM]
FROM [MY_PROJ].[dbo].[EVNT_CHG_LOG]
WHERE DATA_XML_TXT.value('(/ChangeSet/Change/Table/ChangedFields/UD_USER_ID)[0]','varchar(50)') like '%3123%'
But when I execute the query, I don't get any results.
I tested the following XQuery, and it should give you what you need:
SELECT TOP 1000 [CHG_LOG_ID]
, [EVNT_ID]
, [DATA_XML_TXT]
, [UD_DTTM]
FROM [MY_PROJ].[dbo].[EVNT_CHG_LOG]
WHERE DATA_XML_TXT.value('(/ChangeSet/Change/Table/ChangedFields/Field[#FieldName="UD_USER_ID"]/#Current)[1]','varchar(50)') like '%3123%'
Note: Indexing for XQuery starts at 1 instead of 0

Resources