SQL Server XQuery.modify "Syntax error near ':', expected '}'" - sql

Table Test.User contains one field "Details" which is in XML type.
The Details value of user which Id is 1024 is in the following format:
<Details>
<Name>Kevin</Name>
<Age>23</Age>
</>Details>
I try to insert a new node "Address" into this xml value likes this:
UPDATE Test.User
SET Details.modify('insert <Address>{0:c0}</Address> into (/Details)[1]')
WHERE Id = 1024
But error occurs, please help advise on it.
"Syntax error near ':', expected '}'"

You need to escape these types of {0:c0} markup characters with CDATA section
DECLARE #DETAILS XML ='<Details>
<Name>Kevin</Name>
<Age>23</Age>
</Details>'
SELECT #DETAILS
SET #DETAILS.modify('insert <Address><![CDATA[{0:c0}]]></Address> into (/Details)[1]')
SELECT #DETAILS
Then the result will be like
<Details>
<Name>Kevin</Name>
<Age>23</Age>
<Address>{0:c0}</Address>
</Details>

Related

Extract xml value from table SQL Server

I am trying to extract value from xml in table.PFB sample xml.
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfKeyValue xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<KeyValue>
<Key>[#Id#]</Key>
<Value>354005</Value>
</ArrayOfKeyValue>
I am trying below script and it is not working.
SELECT
CAST(CAST(([KeyWordValues]) AS ntext) AS XML).value('(/ArrayOfKeyValue/KeyValue[1])', 'nvarchar(max)')
FROM
Table
I'm getting this error :
Msg 2389, Level 16, State 1, Line 1
XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
Please note XML is saved as varchar in the database.
Please help. Thanks in advance
Thanks alot for help. I got it working.
SELECT cast(cast(([KeyWordValues]) as ntext) as
xml).value('(/ArrayOfKeyValue/KeyValue/Value)[1]', 'nvarchar(max)')
FROM Table

Getting node value in xml column

Please let me know why the following XML query is not fetching any result.
I am trying to get value EffectiveUserName tag.
DECLARE #MyXML XML
SET #MyXML = '<PropertyList xmlns="urn:schemas-microsoft-com:xml-analysis" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<Catalog>name</Catalog>
<Timeout>600</Timeout>
<Format>Native</Format>
<DbpropMsmdFlattened2>false</DbpropMsmdFlattened2>
<Cube>Model</Cube>
<DbpropMsmdOptimizeResponse>1</DbpropMsmdOptimizeResponse>
<DbpropMsmdActivityID>68A6900B-20F8-4A02-AEC3-7C56B2D3C5D5</DbpropMsmdActivityID>
<DbpropMsmdRequestID>A0D1E07F-AE29-4CCA-AEE4-3B79D97CA426</DbpropMsmdRequestID>
<DbpropMsmdCurrentActivityID>68A6900B-20F8-4A02-AEC3-7C56B2D3C5D5</DbpropMsmdCurrentActivityID>
<LocaleIdentifier>1033</LocaleIdentifier>
<EffectiveUserName>userid#domainname.com</EffectiveUserName>
<sspropinitappname>PowerBI</sspropinitappname>
</PropertyList>'
select #MyXML.value('(/PropertyList/EffectiveUserName)[1]','varchar(max)')
Your XML has a default namespace that you must respect and include in your query!
<PropertyList xmlns="urn:schemas-microsoft-com:xml-analysis"
***********************************************
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
Use this code to grab the value you're looking for by defining the default XML namespace for your query:
;WITH XMLNAMESPACES(DEFAULT 'urn:schemas-microsoft-com:xml-analysis')
SELECT
#MyXML.value('(/PropertyList/EffectiveUserName)[1]', 'varchar(50)')
You can ignore the namespace by using *: before the tag names:
select #MyXML.value('(/*:PropertyList/*:EffectiveUserName)[1]','varchar(max)')

SQL Query Column with XML Data

I have the following data in a column, how can I query the values inside.
<deliveryPart notificationId="12345">
<message address="email#email.com" content="multipart/alternative" domain="email.com" format="0" id="159436637" recipient-id="098765" targetCode="__MAIN__">
<custom>
<recipient Nickname="mynickname" id="54321" />
<targetData Incident_Id="1509403" reference_nb="0000-0000" />
</custom>
</message>
</deliveryPart>
I gave it a quick go but I've never done it before and I am in short of time.
select top 10 *
from [db].[db].[table]
where mData.value('(deliveryPart/message/recipient-id)[1]','varchar(max)') like '098765'
I get the following error
Msg 4121, Level 16, State 1, Line 1
Cannot find either column "mData" or the user-defined function or aggregate "mData.value", or the name is ambiguous.
UPDATE
I am using the following code to fetch the xml values and it works
SELECT TOP 1000 B1.[mData].value('(deliveryPart/message/#id)[1]', 'NVARCHAR(MAX)') AS 'MessageID', B1.[mData].value('(deliveryPart/message/#address)[1]', 'NVARCHAR(MAX)') AS 'Address'
FROM (SELECT CAST(mData as XML) as xmlData FROM [dbo].[db].[table]) B0
CROSS APPLY xmlData.nodes('/') B1 (mData)
WHERE B1.[mData].value('(deliveryPart/message/#address)[1]', 'NVARCHAR(MAX)') LIKE '%#%'
And it returns the xml values store in the ntext field just fine.
180646774 email1#email.com
159436627 test2#hotmail.com
159436637 test3#hotmail.com
However, I need to fetch values from outside the mData column and is not letting me do it.
You need to use the #recipient-id as a XML attribute - not XML element:
<message address="email#email.com" content="multipart/alternative"
domain="email.com" format="0" id="159436637"
recipient-id="098765" targetCode="__MAIN__">
************ this is an *attribute* - use the `#` to select it!
Code:
select top 10 *
from [db].[db].[table]
where mData.value('(deliveryPart/message/#recipient-id)[1]', 'varchar(max)') like '098765'

Xml query resulting in error in sql server

This is my xml query
declare #XML xml
set #XML=
'<ROOT>
<Customers>
<CustomerId>1111</CustomerId>
<CompanyName>Sean Chai</CompanyName>
<City>NY</City>
</Customers>
<Customers>
<CustomerId>1112</CustomerId>
<CompanyName>Tom Johnston</CompanyName>
<City>LA</City>
</Customers>
<Customers>
<CustomerId>1113</CustomerId>
<CompanyName>Institute of Art</CompanyName>
</Customers>
</ROOT>';
SELECT
R.Node('.').value('(/Customers/CustomerId/.)[1]','varchar(100)') AS CustomerID,
R.Node('.').value('(/Customers/CompanyName/.)[1]','varchar(100)') AS CompanyName
FROM #XML.nodes('/ROOT/Customers') R(Node)
But its giving error:
Msg 4121, Level 16, State 1, Line 20
Cannot find either column "R" or the user-defined function or aggregate "R.Node", or the name is ambiguous.
i searched but couldn't get R.node Thing pls somebody guide me onthis !
and i'm not understanding #XML.nodes('/ROOT/Customers') R(Node) ?
what is its use in query!
Change the query like this and try
SELECT
R.Node.value('(CustomerId/.)[1]','varchar(100)') AS CustomerID,
R.Node.value('(CompanyName/.)[1]','varchar(100)') AS CompanyName
FROM #XML.nodes('/ROOT/Customers') R(Node)
First of all you have syntax error in your query. You have aliase to your resultant table as R(Node), then you cannot specifiy the path as R.Node(.).
Secondly the path that you mentioned in your query is wrong (/Customers/CustomerId/.)

Getting the value of dc:creator using SQL XML

I am unsure how to get the value of dc:creator from an RSS-feed using SQL.
This is my xml/rss-feed:
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<title>Foobar RSS</title>
<link>http://www.foobar.com/</link>
<description>RSS feed</description>
<language>en</language>
<ttl>15</ttl>
<item>
<title>This is my title</title>
<link>http://www.foobar.com/link/blabla</link>
<description>Bla..bla..bla..</description>
<dc:creator>John Doe</dc:creator>
<guid isPermaLink="false">00082EA751F1D905DE00E7CFA2417DA9</guid>
<pubDate>Wed, 26 Oct 2011 00:00:00 +0200</pubDate>
</item>
</channel>
</rss>
In my SQL I use something like this to get the values - e.g for pubDate I use something like this:
DECLARE #xml XML
SET #xml = cast('my rss feed here' AS xml)
SELECT
convert(datetime,substring(T.nref.value('pubDate[1]','nvarchar(100)'),6,20)) as pubdate,
FROM #xml.nodes('//item') AS T(nref)
This works fine, but when I am trying to get dc:creator value 'John Doe', the following just gives me an error:
SELECT
T.nref.value('dc:creator','nvarchar(100)') as creator
FROM #xml.nodes('//item') AS T(nref)
error:
XQuery [value()]: The name "dc" does not denote a namespace.
I need to be able to select multiple columns from the rss-feed. Can anybody provide a solution or direction to get the value of dc:creator?
I have another question - how would you construct the code if you are doing it in a sub select?
E.g.
INSERT INTO RSSResults (ID, pubDate)
SELECT #ID, tbl.pubDate FROM (
;WITH XMLNAMESPACES('http://purl.org/dc/elements/1.1/' AS dc)
SELECT
RSS.Item.value('(dc:creator)[1]', 'nvarchar(100)') as pubDate
FROM
#xml.nodes('/rss/channel/item') as RSS(Item)) AS tbl
The code breaks at ";WITH XMLNAMESPACES". Is it possible to include the namespace directly in the statement somehow?
Try something like this:
DECLARE #xml XML
SET #xml = cast('my rss feed here' AS xml)
;WITH XMLNAMESPACES('http://purl.org/dc/elements/1.1/' AS dc)
SELECT
#xml.value('(rss/channel/item/dc:creator)[1]', 'nvarchar(100)')
If you need to catch multiple items - try this:
DECLARE #xml XML
SET #xml = cast('my rss feed here' AS xml)
;WITH XMLNAMESPACES('http://purl.org/dc/elements/1.1/' AS dc)
SELECT
RSS.Item.value('(dc:creator)[1]', 'nvarchar(100)')
FROM
#xml.nodes('/rss/channel/item') as RSS(Item)