read XML in SQL, no data being pulled - sql

I am trying to retrieve data from an XML file. Below is how the XML doc looks and below that is my SQL code. It will run the code and show column headers - but will not populate with any data. What am I missing?
<profile xmlns="http://feed.elasticstats.com/schema/mma/v1/participants-profile.xsd" generated="2015-12-10T17:34:54Z">
<fighters>
<fighter id="01585452-852a-4b40-a6dc-fdd04279f02c" height="72" weight="170" reach="" stance="" first_name="Sai" nick_name="The Boss" last_name="Wang">
<record wins="6" losses="4" draws="1" no_contests="0" />
<born date="1988-01-16" country_code="UNK" country="Unknown" state="" city="" />
<out_of country_code="UNK" country="Unknown" state="" city="" />
</fighter>
<fighter id="0168dd6b-b3e1-4954-8b71-877a63772dec" height="" weight="0" reach="" stance="" first_name="Enrique" nick_name="Wasabi" last_name="Marin">
<record wins="8" losses="2" draws="0" no_contests="0" />
<born date="" country_code="UNK" country="Unknown" state="" city="" />
<out_of country_code="UNK" country="Unknown" state="" city="" />
</fighter>
DECLARE #x xml
SELECT #x = P
FROM OPENROWSET (BULK 'C:\Python27\outputMMA.xml', SINGLE_BLOB) AS FIGHTERS(P)
DECLARE #hdoc int
EXEC sp_xml_preparedocument #hdoc OUTPUT, #x
SELECT *
FROM OPENXML (#hdoc, '/fighters/fighter', 1) --1\ IS ATTRIBUTES AND 2 IS ELEMENTS
WITH (
id varchar(100),
height varchar(10),
last_name varchar(100)
) --THIS IS WHERE YOU SELECT FIELDS you want returned
EXEC sp_xml_removedocument #hdoc

FROM OPENXML is not the best approach any more. Try it like this:
Just copy this into an empty query window and execute:
DECLARE #xml XML=
'<profile xmlns="http://feed.elasticstats.com/schema/mma/v1/participants-profile.xsd" generated="2015-12-10T17:34:54Z">
<fighters>
<fighter id="01585452-852a-4b40-a6dc-fdd04279f02c" height="72" weight="170" reach="" stance="" first_name="Sai" nick_name="The Boss" last_name="Wang">
<record wins="6" losses="4" draws="1" no_contests="0" />
<born date="1988-01-16" country_code="UNK" country="Unknown" state="" city="" />
<out_of country_code="UNK" country="Unknown" state="" city="" />
</fighter>
<fighter id="0168dd6b-b3e1-4954-8b71-877a63772dec" height="" weight="0" reach="" stance="" first_name="Enrique" nick_name="Wasabi" last_name="Marin">
<record wins="8" losses="2" draws="0" no_contests="0" />
<born date="" country_code="UNK" country="Unknown" state="" city="" />
<out_of country_code="UNK" country="Unknown" state="" city="" />
</fighter>
</fighters>
</profile>';
WITH XMLNAMESPACES(DEFAULT 'http://feed.elasticstats.com/schema/mma/v1/participants-profile.xsd')
SELECT One.fighter.value('#id','uniqueidentifier') AS Fighter_ID
,One.fighter.value('#height','int') AS Fighter_Height
,One.fighter.value('#weight','int') AS Fighter_Weigth
,One.fighter.value('#reach','varchar(100)') AS Fighter_Height
,One.fighter.value('#stance','varchar(100)') AS Fighter_Height
,One.fighter.value('#first_name','varchar(100)') AS Fighter_FirstName
,One.fighter.value('#nick_name','varchar(100)') AS Fighter_NickName
,One.fighter.value('#last_name','varchar(100)') AS Fighter_LastName
,One.fighter.value('record[1]/#wins','int') AS FighterRecord_Wins
,One.fighter.value('record[1]/#draws','int') AS FighterRecord_Draws
,One.fighter.value('record[1]/#no_contests','int') AS FighterRecord_NoContest
,One.fighter.value('born[1]/#date','date') AS FighterBorn_Date
,One.fighter.value('born[1]/#country_code','varchar(10)') AS FighterBorn_CountryCode
,One.fighter.value('born[1]/#country','varchar(100)') AS FighterBorn_Country
,One.fighter.value('born[1]/#state','varchar(100)') AS FighterBorn_State
,One.fighter.value('born[1]/#city','varchar(100)') AS FighterBorn_City
,One.fighter.value('out_of[1]/#country_code','varchar(10)') AS FighterOutOf_CountryCode
,One.fighter.value('out_of[1]/#country','varchar(100)') AS FighterOutOf_Country
,One.fighter.value('out_of[1]/#state','varchar(100)') AS FighterOutOf_State
,One.fighter.value('out_of[1]/#city','varchar(100)') AS FighterOutOf_City
FROM #xml.nodes('/profile/fighters/fighter') AS One(fighter)

Firstly repair the data (:xs, </fighters>, </profile>)
<profile xmlns:xs="http://feed.elasticstats.com/schema/mma/v1/participants-profile.xsd" generated="2015-12-10T17:34:54Z">
<fighters>
<fighter id="01585452-852a-4b40-a6dc-fdd04279f02c" height="72" weight="170" reach="" stance="" first_name="Sai" nick_name="The Boss" last_name="Wang">
<record wins="6" losses="4" draws="1" no_contests="0" />
<born date="1988-01-16" country_code="UNK" country="Unknown" state="" city="" />
<out_of country_code="UNK" country="Unknown" state="" city="" />
</fighter>
<fighter id="0168dd6b-b3e1-4954-8b71-877a63772dec" height="" weight="0" reach="" stance="" first_name="Enrique" nick_name="Wasabi" last_name="Marin">
<record wins="8" losses="2" draws="0" no_contests="0" />
<born date="" country_code="UNK" country="Unknown" state="" city="" />
<out_of country_code="UNK" country="Unknown" state="" city="" />
</fighter>
</fighters>
</profile>
Then the code
FROM OPENXML (#docHandle, 'profile/fighters/fighter', 1)
and we are done
01585452-852a-4b40-a6dc-fdd04279f02c 72 Wang
0168dd6b-b3e1-4954-8b71-877a63772dec Marin

You have an undeclared namespace in your XML document. Consider the revision declaring the namespace and referencing it in xpath expression:
DECLARE #x xml;
SELECT #x = P
FROM OPENROWSET (BULK 'C:\Python27\outputMMA.xml', SINGLE_BLOB) AS FIGHTERS(P)
DECLARE #hdoc int
EXEC sp_xml_preparedocument #hdoc OUTPUT, #x,
'<root xmlns:doc="http://feed.elasticstats.com/schema/mma/v1/participants-profile.xsd"/>'
SELECT *
FROM OPENXML (#hdoc, '/doc:profile/doc:fighters/doc:fighter', 1)
WITH (
id varchar(100),
height varchar(10),
last_name varchar(100)
)
EXEC sp_xml_removedocument #hdoc

Related

Get XML from different Tables

Good day to you!
I have a question. Can't get how combine 2 tables in 1 result XML.
Here is the sample
DECLARE #t1 table (ID int identity(1,1), SomeField varchar(50))
DECLARE #t2 table (ID int identity(1,1), SomeField varchar(50), AnotherField varchar(50))
INSERT INTO #t1 (SomeField) VALUES ('rec1'),('rec2'),('rec3'),('rec4')
INSERT INTO #t2 (SomeField,AnotherField) VALUES ('s106','here'),('s12','just'),('s13','sample')
SELECT * FROM #t1 AS FirstTable
SELECT * FROM #t2 AS AnotherTable
Wanted result:
<Root>
<FirstTable ID="1" SomeField="rec1" />
<FirstTable ID="2" SomeField="rec2" />
<FirstTable ID="3" SomeField="rec3" />
<FirstTable ID="4" SomeField="rec4" />
<AnotherTable ID="1" SomeField="s106" AnotherField="here" />
<AnotherTable ID="2" SomeField="s12" AnotherField="just" />
<AnotherTable ID="3" SomeField="s13" AnotherField="sample" />
</Root>
dbfiddle here
New remark (edited)
answered by John Cappelletti, but need put all this inside third table.
Here is new code:
DECLARE #t1 table (ID int identity(1,1), tID int, SomeField varchar(50))
DECLARE #t2 table (ID int identity(1,1), tID int, SomeField varchar(50), AnotherField varchar(50))
DECLARE #t3 table (ID int identity(1,1), field1 varchar(50), field2 varchar(50))
INSERT INTO #t1 (tID,SomeField) VALUES (1,'rec1'),(1,'rec2'),(1,'rec3'),(1,'rec4')
INSERT INTO #t2 (tID,SomeField,AnotherField) VALUES (1,'s106','here'),(1,'s12','just'),(1,'s13','sample')
INSERT INTO #t3 (field1,field2) VALUES ('field1 Value','field2 Value')
Wanted result (finally):
<ThirdTable ID="1" field1="field1 Value" field2="field2 Value">
<FirstTable ID="1" tID="1" SomeField="rec1" />
<FirstTable ID="2" tID="1" SomeField="rec2" />
<FirstTable ID="3" tID="1" SomeField="rec3" />
<FirstTable ID="4" tID="1" SomeField="rec4" />
<AnotherTable ID="1" tID="1" SomeField="s106" AnotherField="here" />
<AnotherTable ID="2" tID="1" SomeField="s12" AnotherField="just" />
<AnotherTable ID="3" tID="1" SomeField="s13" AnotherField="sample" />
</ThirdTable>
Select [root] = cast((Select * From #t1 for xml raw('FirstTable'))
+(Select * From #t2 for xml raw('AnotherTable'))
as xml)
For XML Path(''),Type
Returns
<root>
<FirstTable ID="1" SomeField="rec1" />
<FirstTable ID="2" SomeField="rec2" />
<FirstTable ID="3" SomeField="rec3" />
<FirstTable ID="4" SomeField="rec4" />
<AnotherTable ID="1" SomeField="s106" AnotherField="here" />
<AnotherTable ID="2" SomeField="s12" AnotherField="just" />
<AnotherTable ID="3" SomeField="s13" AnotherField="sample" />
</root>
Added for the Extended Question
Select *
,(select cast(
isnull((Select * From #t1 for xml raw('FirstTable')),'')
+isnull((Select * From #t2 for xml raw('AnotherTable')),'')
as xml)
)
From #t3 for xml raw('ThirdTable')
Returns
<ThirdTable ID="1" field1="field1 Value" field2="field2 Value">
<FirstTable ID="1" tID="1" SomeField="rec1" />
<FirstTable ID="2" tID="1" SomeField="rec2" />
<FirstTable ID="3" tID="1" SomeField="rec3" />
<FirstTable ID="4" tID="1" SomeField="rec4" />
<AnotherTable ID="1" tID="1" SomeField="s106" AnotherField="here" />
<AnotherTable ID="2" tID="1" SomeField="s12" AnotherField="just" />
<AnotherTable ID="3" tID="1" SomeField="s13" AnotherField="sample" />
</ThirdTable>

How to get value from XML in stored procedure?

Can you all help me for this problem?
I want to get value from following XML in sql stored procedure. I don't get vlaue if 'xsi:type="ActiveDirectoryItem"' is in tag 'anyType', and 'ActiveDirectoryItems' tag is also with URLs. How can i do to get only values?
<?xml version="1.0" encoding="utf-8" ?>
<ActiveDirectoryItems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Items>
<anyType xsi:type="ActiveDirectoryItem">
<FirstName />
<MiddleInitial />
<LastName />
<DisplayName>Migrate-group</DisplayName>
<UserPrincipalName />
<PostalAddress />
<ResidentialAddress />
<Title />
<HomePhone />
<OfficePhone />
<Mobile />
<Fax />
<Email>Migrate-group#gmail.com</Email>
<Url />
<AccountName>Migrate-group</AccountName>
<DistinguishedName />
<IsAccountActive>false</IsAccountActive>
<ManagedBy />
<Manager />
<CompareType>0</CompareType>
<Description />
<Department />
<Company />
<Type />
</anyType>
</Items>
<GlobalCatalog />
</ActiveDirectoryItems>
The format i want to get is as the following:
DisplayName Email Account Name
Migrate-group Migrate-group#gmail.com Migrate-group
you can use the value keyword
Example:
DECLARE #MyXml XML = '<Root><SomeData>100</SomeData></Root>'
DECLARE #Something INT
SELECT #Something = #MyXml.value('(//Root/SomeData)[1]', 'INT')

XML Join in sql server

I am trying to join the two xml response in stored procedure with the below mentioned code .The output that i was looking from my select query was
declare #cdoValuation xml
declare #marketColorPrice xml
set #cdoValuation = '<Response>
<CDOValuation id="BAB12-II.A2" mv="1.019358126500000e+002" run_date="2014-04-30T00:00:00" />
<CDOValuation id="BABS12-I.C" mv="9.915358793000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="BLUEMTN.A2" mv="9.925446292000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="BLUEMTN3.C" mv="9.472908099999999e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="CGMS11-1.D" mv="9.644486014000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="CSQUARE4.A" mv="9.880319818000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="CSQUARE4.C" mv="9.295238056000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="MADPK5.C" mv="9.735145883000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="MADPK7.PS" mv="9.225345985000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="MADPK8.A" mv="9.984445828000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="OHAPARK.B" mv="9.652910265000000e+001" run_date="2014-04-30T00:00:00" />
<CDOValuation id="SDAYTONA.B2L" mv="9.590162241000000e+001" run_date="2014-04-30T00:00:00" />
</Response>'
set #marketColorPrice = '<Response>
<MarketColorPrice tranche_id="BAB12-II.A2" mk_price="1.001533333333333e+002" mk_date="2013-12-19T00:00:00" mk_source1="Empirasign/SCI" mk_source2="Cvr, Talk" mk_record_type="bwic, pxtalk" />
<MarketColorPrice tranche_id="BLUEMTN.A2" mk_price="9.877000000000000e+001" mk_date="2013-12-16T00:00:00" mk_source1="Empirasign/SCI" mk_source2="Cvr, Talk" mk_record_type="bwic, pxtalk" />
<MarketColorPrice tranche_id="BLUEMTN3.C" mk_price="8.050000000000000e+001" mk_date="2013-05-15T00:00:00" mk_source1="Empirasign/SCI" mk_source2="Talk, Trade" mk_record_type="bwic, pxtalk" />
<MarketColorPrice tranche_id="CSQUARE4.A" mk_price="9.765294117647059e+001" mk_date="2014-04-08T00:00:00" mk_source1="Empirasign/SCI" mk_source2="Cvr, Talk" mk_record_type="bwic, pxtalk" />
<MarketColorPrice tranche_id="CSQUARE4.C" mk_price="9.125000000000000e+001" mk_date="2014-05-15T00:00:00" mk_source1="Empirasign" mk_source2="Talk" mk_record_type="market" />
<MarketColorPrice tranche_id="MADPK5.C" mk_price="9.200000000000000e+001" mk_date="2013-10-24T00:00:00" mk_source1="SCI" mk_source2="Cvr" />
<MarketColorPrice tranche_id="MADPK7.PS" mk_price="1.133333333333333e+002" mk_date="2013-08-28T00:00:00" mk_source1="Empirasign/SCI" mk_source2="Cvr, Talk" mk_record_type="bwic, pxtalk" />
<MarketColorPrice tranche_id="OHAPARK.B" mk_price="9.787500000000000e+001" mk_date="2014-04-21T00:00:00" mk_source1="Empirasign" mk_source2="Talk" mk_record_type="market" />
</Response>'
declare #responseXml xml
set #responseXml =(select cdoValuation.cdoValuationcol.value('(//CDOValuation/#mv)[1]', 'float') as "#mv",
dbo.ToShortDateString(cdoValuation.cdoValuationcol.value('(//CDOValuation/#run_date)[1]', 'datetime')) as "#run_date",
marketColorPrice.marketColorPricecol.value('(//MarketColorPrice/#mk_price)[1]', 'float') as "#mk_price",
marketColorPrice.marketColorPricecol.value('(//MarketColorPrice/#mk_source1)[1]', 'varchar(30)') as "#mk_source1",
marketColorPrice.marketColorPricecol.value('(//MarketColorPrice/#mk_source2)[1]', 'varchar(30)') as "#mk_source2"
from #cdoValuation.nodes('/CDOValuation') cdoValuation(cdoValuationcol)
inner join #marketColorPrice.nodes('/MarketColorPrice') marketColorPrice(marketColorPricecol)
on marketColorPrice.marketColorPricecol.value('(//MarketColorPrice/tranche_id)[1]', 'VARCHAR(20)') =
cdoValuation.cdoValuationcol.value('(//CDOValuation/id)[1]', 'VARCHAR(20)') FOR XML PATH('BWICResult')
, ROOT('Response'))
select #responseXml
The output that i was expecting was of the following format but
doesnt seems to be the case .Can someone help me out to know as to what should be done ?
<Response> <BWICResult tranche_id="BAB12-II.A2" mv="1.019358126500000e+002" mk_price="1.001533333333333e+002"/> <BWICResult tranche_id="BLUEMTN.A2" mv="9.925446292000000e+001" mk_price="9.877000000000000e+001"/> </Response>
select C.X.value('#id', 'varchar(20)') as '#id',
C.X.value('#mv', 'float') as '#mv',
M.X.value('#mk_price', 'float') as '#mk_price'
from #cdoValuation.nodes('/Response/CDOValuation') as C(X)
inner join #marketColorPrice.nodes('Response/MarketColorPrice') as M(X)
on C.X.value('#id', 'varchar(20)') = M.X.value('#tranche_id', 'varchar(20)')
for xml path('BWICResult'), root('Response')
Result:
<Response>
<BWICResult id="BAB12-II.A2" mv="1.019358126500000e+002" mk_price="1.001533333333333e+002" />
<BWICResult id="BLUEMTN.A2" mv="9.925446292000000e+001" mk_price="9.877000000000000e+001" />
<BWICResult id="BLUEMTN3.C" mv="9.472908099999999e+001" mk_price="8.050000000000000e+001" />
<BWICResult id="CSQUARE4.A" mv="9.880319818000000e+001" mk_price="9.765294117647059e+001" />
<BWICResult id="CSQUARE4.C" mv="9.295238056000000e+001" mk_price="9.125000000000000e+001" />
<BWICResult id="MADPK5.C" mv="9.735145883000000e+001" mk_price="9.200000000000000e+001" />
<BWICResult id="MADPK7.PS" mv="9.225345985000000e+001" mk_price="1.133333333333333e+002" />
<BWICResult id="OHAPARK.B" mv="9.652910265000000e+001" mk_price="9.787500000000000e+001" />
</Response>

How to remove xml nodes without attribute in Sql Server

What is the correct way to remove all child nodes of the root node with a missing attribute from an xml field in Sql Server 2008?
My Xml looks like this, I want to remove all the child nodes of <root> that don't have the ln attribute specified
<root>
<title />
<title />
<questionphrase ln="nl">
<xhtml />
</questionphrase>
<questionphrase ln="en">
<xhtml />
</questionphrase>
<information ln="nl">
<xhtml />
</information>
<information ln="en">
<xhtml />
</information>
<title />
<title ln="en">
value
</title>
<label ln="en">
value
</label>
<title />
<title />
</root>
After the delete the xml should look like this
<root>
<questionphrase ln="nl">
<xhtml />
</questionphrase>
<questionphrase ln="en">
<xhtml />
</questionphrase>
<information ln="nl">
<xhtml />
</information>
<information ln="en">
<xhtml />
</information>
<title ln="en">
value
</title>
<label ln="en">
value
</label>
</root>
Try this:
DECLARE #xml XML = '....'
SET #xml.modify('delete //root/*[not(#ln)]')
SQL FIDDLE DEMO

T-SQL Dynamic xquery

I am trying to figure out how I can load my table variable with data from XML using dynamic xquery? I am getting a result set of nodes from the query and defining the value type of those nodes. It seems that it is the value definition of the nodes that it is blowing up on.
Here is an example of the script that works, but is not dynamic.
Script:
DECLARE #XML XML = '<root>
<data>
<list id="organization" label="Organization">
<options>
<item value="1" label="Organization1" selected="false" />
<item value="2" label="Organization2" selected="false" />
<item value="3" label="Organization3" selected="false" />
<item value="4" label="Organization4" selected="true" />
<item value="5" label="Organization5" selected="true" />
</options>
</list>
</data>
</root>';
DECLARE #Orgs TABLE (ID INT);
Insert Into #Orgs(ID) Select OrgNameIdNodes.ID.value('#value','int') from #xml.nodes('//*[#id="organization"]//item[#selected="true"]') as OrgNameIdNodes(ID);
Select *
from #orgs
What I would like to be able to do is pass in parameters for both value and the #xml.nodes sections so I would have something like:
Insert Into #Orgs(ID) Select OrgNameIdNodes.ID.value(#Value) from #xml.nodes(#Nodes) as OrgNameIdNodes(ID);
Is this possible?
How about using sp_executesql with dynamic sql. Something like:
DECLARE #XML XML = '<root>
<data>
<list id="organization" label="Organization">
<options>
<item value="1" label="Organization1" selected="false" />
<item value="2" label="Organization2" selected="false" />
<item value="3" label="Organization3" selected="false" />
<item value="4" label="Organization4" selected="true" />
<item value="5" label="Organization5" selected="true" />
</options>
</list>
</data>
</root>';
declare #orgs table(ID int);
declare #nodes nvarchar(4000),
#value nvarchar(4000),
#query nvarchar(4000)
select #value = '''#value'',''int'''
select #nodes = '//*[#id="organization"]//item[#selected="true"]'
select #query = 'Select OrgNameIdNodes.ID.value( ' + #value + ') ' +
'from #xml.nodes(''' + #nodes + ''') as OrgNameIdNodes(ID)'
insert into #Orgs(ID) EXEC sp_executesql #query, N'#xml xml', #xml = #xml
Select *
from #orgs