XML Output from SQL Server 2008 - sql

I am trying to create an XML output from SQL that has 3 nested statements but have pretty minimal experience in this area. The code I've written is below:
select
replace(replace(replace(
(
select ID as [#ID],
(select cast(Name as int) as [#Name],
(select num as [#Number],
from #tbl_new_claims_export
for xml path('Num'),root('Numbers'), type
)
from #tbl_new_claims_export
for xml path('LineItem'), type
)
from #tbl_new_claims_export
for XML PATH('Line'),ROOT('Lines')
),'><','>'+char(10)+'<'),'<Num', char(9)+'<Num'), '<Num>', char(9)+'<Num>') ;
I am trying to create an output that looks like this:
<Lines>
<Line ID ="1">
<LineItem Name ="Michael"/>
<Numbers>
<Num Number="24"</Num>
</Numbers>
</LineItem>
</Line>
For each Line, I want to see the Line, Name, and Number as shown above. However, it is showing multiple Names under each Line and then repeats the Number below. Can anybody help me troubleshoot this code?
Thanks.

Without sample data with 1:n examples and the expected output it is reading in the magic glass bulb...
Anyway, this
SELECT
1 AS [Line/#ID]
,'Michael' AS [LineItem/#Name]
,24 AS [Numbers/Num/#Number]
FOR XML PATH('Lines')
will produce exactly the output you specify:
<Lines>
<Line ID="1" />
<LineItem Name="Michael" />
<Numbers>
<Num Number="24" />
</Numbers>
</Lines>
If you need further help, please specify a minimal and reduced test scenario. Best would be a fiddle or some pasteable code like
DECLARE #tbl TABLE(ID INT, col1 VARCHAR(MAX)/*more columns*/);
INSERT INTO #tbl VALUES (1,'test1')/*more values*/

Related

Extract field from XML Data in SQL

I have an issue as I never done that before.
I have an SQL table with the following :
ID int;
xml_record xml;
The xml record is looking like that :
<root xml:space="preserve" id="XXX">
<c1>Data1</c1>
<c2>Data2</c2>
<c3>Data3</c3>
...
<cn>DataN</cn>
</root>
However I tried to use the following query with no success (return null) :
SELECT xml_record.value('c1[1]','varchar(50)') as value_c1
FROM myTable
The problem might come from the "space" but not sure.
You just need to fix the expression:
SELECT xml_record.value('(/root/c1)[1]','varchar(50)') AS value_c1
FROM ...
SELECT
xml_record.value
( '(/root/c1/text())[1])',
'varchar(50)') as value_c1
FROM myTable
else remove the first xml line

How do I get a value from XML column in SQL?

So, I have a table with a large chunk of data stored in XML.
The partial XML schema (down to where I need) looks like this:
<DecisionData>
<Customer>
<SalesAttemptNumber />
<SubLenderID>IN101_CNAC</SubLenderID>
<DecisionType>Decision</DecisionType>
<DealerID />
<CustomerNumber>468195994772076</CustomerNumber>
<CustomerId />
<ApplicationType>Personal</ApplicationType>
<ApplicationDate>9/16/2008 11:32:07 AM</ApplicationDate>
<Applicants>
<Applicant PersonType="Applicant">
<CustNum />
<CustomerSSN>999999999</CustomerSSN>
<CustLastName>BRAND</CustLastName>
<CustFirstName>ELIZABETH</CustFirstName>
<CustMiddleName />
<NumberOfDependants>0</NumberOfDependants>
<MaritalStatus>Single</MaritalStatus>
<DateOfBirth>1/1/1911</DateOfBirth>
<MilitaryRank />
<CurrentAddress>
<ZipCode>46617</ZipCode>
Unfortunately, I am unfamiliar with pulling from XML, and my google-fu has failed me.
select TransformedXML.value('(/DecisionData/Customer/Applicants/Applicant PersonType="Applicant"/CurrentAddress/ZipCode/node())[1]','nvarchar(max)') as zip
from XmlDecisionInputText as t
I believe my problem lies with the portion that goes Applicant PersonType="Applicant", but am unsure how to deal with it.
Thanks for any help.
The xpath in its simplest form would be:
TransformedXML.value('(//ZipCode)[1]', 'nvarchar(100)') AS zip
This will find the first ZipCode node anywhere inside your document. If there are multiple, just be specific (as much as you want but not any more):
TransformedXML.value('(/DecisionData/Customer/Applicants/Applicant[#PersonType="Applicant"]/CurrentAddress/ZipCode)[1]', 'nvarchar(100)') AS zip
DB Fiddle
If there are MULTIPLE applicants, you can use a CROSS APPLY
Example
Select A.ID
,B.*
From XmlDecisionInputText A
Cross Apply (
Select PersonType = x.v.value('#PersonType','VARCHAR(150)')
,CustLastName = x.v.value('CustLastName[1]','VARCHAR(150)')
,CustFirstName = x.v.value('CustFirstName[1]','VARCHAR(150)')
,ZipCode = x.v.value('CurrentAddress[1]/ZipCode[1]','VARCHAR(150)')
From XmlDecisionInputText.nodes('DecisionData/Customer/Applicants/*') x(v)
) B

Creating xml for SQL Server stored procedure

I have a function to insert an item into the database. It takes a lot of values as input and the values are passed as XML.
Consider a sample item XML:
<ROOT>
<Item
ItemName="CarlsApplication"
ItemTypeID="2">
<TSDefaultDescription DefaultitemDescription="C:\t.text"/>
<ItemSellers>
<ComputerObject Alias="" DisplayName="" ServiceName="" UserAccount="" />
<ComputerObject Alias="" DisplayName="" ServiceName="" UserAccount="" />
</ItemSellers>
<ItemOwners>
<ItemOwner Alias="rafchen" FirstName="Rafael" LastName="Chenkov"/>
</ItemOwners>
</Item>
</ROOT>
This has to be passed to stored procedure.
Now, each of these individual values in this XML, I have to extract from somewhere else. I can get the individual values like Item name etc, but how do I organize them into an XML that can be passed?
How do I construct this XML from the values I have?
I guess I will have to make some sort of template with this format and then put variables in that template and fill the variables to prepare the template.
Any help is greatly appreciated.
If I understand what you really want, You can use a query like this to generate that XML:
select
ItemName 'Item/#ItemName', --> Node:`Item` Attribute: `ItemName`
ItemTypeId 'Item/#ItemTypeId',
cast((
select
Alias 'ComputerObject/#Alias',
DisplayName 'ComputerObject/#DisplayName',
ServiceName 'ComputerObject/#ServiceName',
UserAccount 'ComputerObject/#UserAccount'
from
ItemSellers
where
ItemSellers.ItemId = Item.ItemId
for xml path('')) as xml) 'Item/ItemSellers', --> Node:`Item` Sub-Node:`ItemSellers`
cast((
select
Alias 'ItemOwner/#Alias',
FirstName 'ItemOwner/#FirstName',
LastName 'ItemOwner/#LastName'
from
ItemOwners
where
ItemOwners.ItemId = Item.ItemId
for xml path('')) as xml) 'Item/ItemOwners'
from
Item
for xml path('ROOT');
SQL Fiddle Demo

Select multiple values in XML file and concatenation them with xQuery

I have the following XML:
<items>
<item value="1"/>
<item value="2"/>
<item value="4"/>
</items>
and I would like to select all item value and concatenate them like this - see below - with XQuery :
1.2.4
Any ideas?
Thanks in advance.
There are two parts to your question:
getting values out of xml
concatenating multiple values together
The second part of your question has been covered off very nicely in the answers to this question.
In terms of getting the values out of your xml, try the below:
-- Your xml variable
DECLARE #xml AS XML = '<items>
<item value="1"/>
<item value="2"/>
<item value="4"/>
</items>'
-- Example of selecting the values into rows
SELECT
item.value('.', 'int')
FROM
#xml.nodes('/items/item/#value') as T1(item)
-- Use your favourite/'best for your circumstance' method of
-- concatenating the rows into one string
-- see https://stackoverflow.com/q/194852/1208914 for other ways
SELECT
item.value('.', 'varchar(50)') + ' ' as 'data()'
FROM
#xml.nodes('/items/item/#value') as T1(item)
for xml path('')
I've put the code above into a sql fiddle that you can access and play with here: http://sqlfiddle.com/#!6/d41d8/18144/0
Using XQuery you can simply select the values using XPath and join them together using a dot.
string-join(/items/item/#value, '.')

selecting an attribute from XML in SQL

Okay, I have a table that has a column called bdParameters, datatype is text. The data stored in the bdParameters column is XML saved as text.
The data goes like this:
<root>
<row statusID="ALL" subID="ALL" viewMaskFields="false" masID="219"
userID="13" prptyDate="08/19/2011" docID="21b15c9e-76a5-44ed-afbb-96b6df2cf881"
resmID="8806" leaID="6345" reshID="3560" doEmail="" emailFrom="" emailTo=""
emailMsg="penarands" emailSubject="" fieldList="1" fmtID="2" OptInCES="Yes"
SendVaiEmailCES="1" RPIPMCURL="blabla#blabla.com" />
<Custom>
<UpdateResidentLetter>
<Row Status="NOTPRINTED" Notes="Created from bulk lettersinterface" />
</UpdateResidentLetter>
</Custom>
</root>
I want to be able to select only the attribute emailMsg from that xml.
Is that possible? If so, how?
Use xml.value with the # symbol to get the attribute
declare #t table (col xml);
insert #t select '
<root><row statusID="ALL" subID="ALL" viewMaskFields="false" masID="219"
userID="13" prptyDate="08/19/2011" docID="21b15c9e-76a5-44ed-afbb-96b6df2cf881"
resmID="8806" leaID="6345" reshID="3560" doEmail="" emailFrom="" emailTo=""
emailMsg="penarands" emailSubject="" fieldList="1" fmtID="2" OptInCES="Yes"
SendVaiEmailCES="1" RPIPMCURL="lm-10-254-9-52.onesitedev.realpage.com" /><Custom>
<UpdateResidentLetter><Row Status="NOTPRINTED" Notes="Created from bulk letters
interface" /></UpdateResidentLetter></Custom></root>';
select col.value('(/root/row/#emailMsg)[1]','varchar(max)') emailMsg
from #t
-- result
penarands