selecting an attribute from XML in SQL - 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

Related

Is there a way to put a header and footer in XML output when using SQL

I’m writing a query that returns data in XML format and I need to add a header that contains some static data, and a footer that contains a count of all of the records in the file. is there a way to do that so that the header and footer only appear once in the file?
my example query is as follows:
SET QUOTED_IDENTIFIER on
SET NOCOUNT ON
DECLARE #XMLTEST XML
SELECT #XMLTEST = (
SELECT GOLFER_NAME AS [GENERAL/NAME],
GOLFER_ID AS [GENERAL/ID],
HANDICAP_INDEX AS [ATTRIBUTES/HANDICAP],
GOLFER_AGE AS [ATTRIBUTES/AGE]
FROM GOLFERS
FOR XML PATH ('row'), Root('root')
)
SET #XMLTEST.modify(
'insert
(
attribute xsi:noNamespaceSchemaLocation {"ARIS_Inbound-v4.0.xsd"}
)
into (/GolfData)[1]')
SELECT #XMLTEST
This returns data in the following format:
<root>
<row>
<general>
<name>woods,tiger</name>
<id>1</id>
</general>
<attributes>
<handicap>4</handicap>
<age>45</age>
</attributes>
</row>
<row>
<general>
<name>fowler,ricky</name>
<id>2</id>
</general>
<attributes>
<handicap>7</handicap>
<age>39</age>
</attributes>
</row>
</root>
Which is what i am looking for but I need to have a header in the file with a format of:
<header>
<version>1.2.113</version>
<author>lincoln,abraham</author>
</header>
and a footer that counts the number of entries (or rows in this case) like this:
<trailer>
<rowcount>2</rowcount>
</trailer>
is this possible?
perhaps I'm overlooking the obvious, but couldn't you concatenate your normal results with your header and footer? Something like:
declare #header varchar(max) = "your header"
declare #footerstart varchar(max) = "your footer start"
declare #footercount int;
declare #footerend varchar(max) = "your footer end"
declare #xmlMiddle varchar(max)
select #xmlMiddle = -- your code that generates the full XML.
--add a select count(*) from your dataset like
select #footercount = from.... where...
select #header + #xmlMiddle + #footerstart + #footercount + #footerend

T-SQL, get value from xml in a column

I have a table with an XML column (xmlCol) and I am trying to query a value from it.
Here's the xml.
<criteria>
<factor name="Rivers" title="Rivers">
<value dataType="Int32" value="1743" description="Wilson0" />
</factor>
<factor name="OptionalAffProperties" title="Include properties">
<value dataType="String" value="FishingModel" description="Fishing Model" />
</factor>
</criteria>
Here is a select to get the column. select xmlCol from MyTable
I am trying to return the value 1743 to a column called RiverID.
Mike
This should work:
SELECT
xmlCol.value('(//factor[#name="Rivers"]/value/#value)[1]', 'int') As RiverID
FROM
MyTable
value() Method (xml Data Type) - SQL Server | Microsoft Docs
XQuery Language Reference (SQL Server) - SQL Server | Microsoft Docs
To get the attribute value, you can query it like so:
select xmlCol.value('(/criteria/factor/value/#value)[1]', 'int') RiverID
from MyTable
You provide the xml path to the record you are looking for: (/criteria/factor/value
And then the attribute you need: /#value)[1].

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

XML Output from SQL Server 2008

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*/

Updating XML attribute in SQL Server XML column

I am trying to update a node of in my XML which is stored in a SQL Server XML column, the line below works if my XML is in a XML element but now I somehow need to change it to XML attributes, apparently the line becomes invalid after the change.
Works for XMLElement:
UPDATE [Customers]
SET voucherXML.modify('replace value of (/ArrayOfCampaignVoucher/CampaignVoucher/Qty/text())[1] with "50"')
WHERE voucherXML.value('(/ArrayOfCampaignVoucher/CampaignVoucher/VouCode)[1]', 'nvarchar(50)') = #VoucherCode
I tried changing the statement like this but no luck, no errors but QTY values doesn't get change to the value of #NewQuantity:
UPDATE [Customers]
SET voucherXML='<ArrayOfCampaignVoucher xmlns:xsd="http://www.w3.org/2001/XMLSchema" Qty="' + CAST(#NewQuantity AS NVARCHAR(16)) + '" />'
WHERE voucherXML.value('(/CampaignVoucher/VouCode)[1]', 'nvarchar(50)') = #VoucherCode
This is how my XML looks in the SQL Server XML column:
<ArrayOfCampaignVoucher xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CampaignVoucher VouCode="Vouc001" Qty="16" />
<CampaignVoucher VouCode="Vouc002" Qty="18" />
<CampaignVoucher xsi:nil="true" />
</ArrayOfCampaignVoucher>
You should use the XQuery functions - not string together your XML like this....
Try this instead:
DECLARE #newquantity INT = 55
UPDATE dbo.Customers
SET voucherXML.modify('replace value of (/ArrayOfCampaignVoucher/CampaignVoucher[#VouCode="Vouc002"]/#Qty)[1] with sql:variable("#NewQuantity") ')
This works for me - the Qty attribute of the node with VouCode="Vouc002" gets updated to the value I defined before in a SQL variable
Update: to insert a new <CampaignVoucher> entry, use XQuery something like this:
UPDATE dbo.Customers
SET voucherXML.modify('insert <CampaignVoucher VouCode="Vouc003" Qty="42" />
as last into (/ArrayOfCampaignVoucher)[1]')