I am struggling with querying a value from an XML. I am new in this world so please forgive me if the answer is actually obvious and i am just not seeing it :)
<documentid>
<id accountingentity="200" lid="...."
variationid="6370">aa0000012</id>
</documentid>
I want to query the value "aa0000012" but I am not able to do it since there is no Xpath for this value available.
I tried it with this query right here but it is only giving me the whole content:
select
#salesorderxml.query('/syncsalesorder/dataarea/salesorder/salesorderheader/documentid/id')
Can anyone please help me? Thanks
This should work whether you have multiple documentid's or not
select o.value('id[1]', 'varchar(max)')
from #salesorderxml.nodes('/documentid') as t(o)
it basically says give me the nodes named documentid, then give me the value of element id
Try this - it will reach into the XML and fetch the element value of <id>:
SELECT
XC.value('text()[1]', 'varchar(100)')
FROM
#salesorderxml.nodes('/documentid/id') AS XT(XC)
This returns:
(No column name)
----------------
aa0000012
Related
I have XML coming in as the input, but I'm unclear on how I need to setup the data and statement to get the values from it. My XML is as follows:
<Keys>
<key>246</key>
<key>247</key>
<key>248</key>
</Keys>
And I want to do the following (is simplified to get my point across)
Select *
From Transaction as t
Inner Join #InputXml.nodes('Keys') as K(X)
on K.X.value('#Key', 'INT') = t.financial_transaction_grp_key
Can anyone provide how I would do that? What would my 3rd/4th line in the SQL look like?
Thanks!
From your code I assume this is SQL-Server but you added the tag [mysql]...
For your next question please keep in mind, that it is very important to know your tools (vendor and version).
Assuming T-SQL and [sql-server] (according to the provided sample code) you were close:
DECLARE #InputXml XML=
N'<Keys>
<key>246</key>
<key>247</key>
<key>248</key>
</Keys>';
DECLARE #YourTransactionTable TABLE(ID INT IDENTITY,financial_transaction_grp_key INT);
INSERT INTO #YourTransactionTable VALUES (200),(246),(247),(300);
Select t.*
From #YourTransactionTable as t
Inner Join #InputXml.nodes('/Keys/key') as K(X)
on K.X.value('text()[1]', 'INT') = t.financial_transaction_grp_key;
What was wrong:
.nodes() must go down to the repeating element, which is <key>
In .value() you are using the path #Key, which is wrong on two sides: 1) <key> is an element and not an attribute and 2) XML is strictly case-sensitive, so Key!=key.
An alternative might be this:
WHERE #InputXml.exist('/Keys/key[. cast as xs:int? = sql:column("financial_transaction_grp_key")]')=1;
Which one is faster depends on the count of rows in your source table as well as the count of keys in your XML. Just try it out.
You probably need to parse the XML to a readable format with regex.
I wrote a similar event to parse the active DB from an xmlpayload that was saved on a table. This may or may not work for you, but you should be able to at least get started.
SELECT SUBSTRING(column FROM IF(locate('<key>',column)=0,0,0+LOCATE('<key>',column))) as KEY FROM table LIMIT 1\G
I have an XML document that I'm working to build a schema for in order to bulk load these documents into a SQL Server table. The XML I'm focusing on looks like this:
<Coverage>
<CoverageCd>BI</CoverageCd>
<CoverageDesc>BI</CoverageDesc>
<Limit>
<FormatCurrencyAmt>
<Amt>30000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>PerPerson</LimitAppliesToCd>
</Limit>
<Limit>
<FormatCurrencyAmt>
<Amt>85000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>PerAcc</LimitAppliesToCd>
</Limit>
</Coverage>
<Coverage>
<CoverageCd>PD</CoverageCd>
<CoverageDesc>PD</CoverageDesc>
<Limit>
<FormatCurrencyAmt>
<Amt>50000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>Coverage</LimitAppliesToCd>
</Limit>
</Coverage>
Inside the Limit element, there's a child LimitAppliesToCd that I need to use to determine where the Amt element's value actually gets stored inside my table. Is this possible to do using the standard XML Bulk Load feature of SQL Server? Normally in XML I'd expect that the element would have an attribute containing the "PerPerson" or "PerAcc" information, but this standard we're using does not call for that.
If anyone has worked with the ACORD standard before, you might know what I'm working with here. Any help is greatly appreciated.
Don't know exactly what you are talking about, but this is a solution to get the information out of your XML.
Assumption: Your XML is already bulk-loaded into a declared variable #xml of type XML:
A CTE will pull the information out of your XML. The final query will then use PIVOT to put your data into the right column.
With a fitting table's structure the actual insert should be simple...
WITH DerivedTable AS
(
SELECT cov.value('CoverageCd[1]','varchar(max)') AS CoverageCd
,cov.value('CoverageDesc[1]','varchar(max)') AS CoverageDesc
,lim.value('(FormatCurrencyAmt/Amt)[1]','decimal(14,4)') AS Amt
,lim.value('LimitAppliesToCd[1]','varchar(max)') AS LimitAppliesToCd
FROM #xml.nodes('/root/Coverage') AS A(cov)
CROSS APPLY cov.nodes('Limit') AS B(lim)
)
SELECT p.*
FROM
(SELECT * FROM DerivedTable) AS tbl
PIVOT
(
MIN(Amt) FOR LimitAppliesToCD IN(PerPerson,PerAcc,Coverage)
) AS p
I'm hoping somebody can help me solve a syntax problem with a TSQL xpath query.
Given the following xml:
<emails>
<email></email>
<email></email>
</emails>
I'm trying to execute the following query:
select * from messages where SendTo.value('(/emails/email)[1]', 'nvarchar(max)') like '%[email value]%'
My query looks only in the first email element and it needs to look in all email elements.
Thanks,
Chris
Try this :-
select * from messages
CROSS APPLY SendTo.nodes('/emails/email') AS Artists(a)
where a.value('(text())[1]', 'nvarchar(max)') like '%[email value]%'
Demo in SQL FIDDLE
My query in HQL is basically:
select functionA(a, :paramA), functionB(b, :paramB), functionC(c, :paramC), sum(d)
from tableA
groupby by functionA(a, :paramA), functionB(b, :paramB), functionC(c, :paramC)
However this gets turned into SQL of
select functionA(a, #param0), functionB(b, #param1), functionC(c, #param2), sum(d)
from tableA
groupby by functionA(a, #param3), functionB(b, #param4), functionC(c, #param5)
Now obviously this is going to throw a 'blah' is invalid in the select list because.... error as the group by clause doesn't match the select clause. I'm about to change this to a string format so I can get on with some productive work but if anyone has the answer as to why NHibernate will not reuse the same named query input the 2 times it is used that would be much appreciated.
A similar question seems to have been asked here with no real answer either.
This has been solved in NHibernate 3.0.0.Alpha1. You can get it here
I have something like the following XML in a column of a table:
<?xml version="1.0" encoding="utf-8"?>
<container>
<param name="paramA" value="valueA" />
<param name="paramB" value="valueB" />
...
</container>
I am trying to get the valueB part out of the XML via TSQL
So far I am getting the right node, but now I can not figure out how to get the attribute.
select xmlCol.query('/container/param[#name="paramB"]') from LogTable
I figure I could just add /#value to the end, but then SQL tells me attributes have to be part of a node. I can find a lot of examples for selecting the child nodes attributes, but nothing on the sibling atributes (if that is the right term).
Any help would be appreciated.
Try using the .value function instead of .query:
SELECT
xmlCol.value('(/container/param[#name="paramB"]/#value)[1]', 'varchar(50)')
FROM
LogTable
The XPath expression could potentially return a list of nodes, therefore you need to add a [1] to that potential list to tell SQL Server to use the first of those entries (and yes - that list is 1-based - not 0-based). As second parameter, you need to specify what type the value should be converted to - just guessing here.
Marc
Depending on the the actual structure of your xml, it may be useful to put a view over it to make it easier to consume using 'regular' sql eg
CREATE VIEW vwLogTable
AS
SELECT
c.p.value('#name', 'varchar(10)') name,
c.p.value('#value', 'varchar(10)') value
FROM
LogTable
CROSS APPLY x.nodes('/container/param') c(p)
GO
-- now you can get all values for paramB as...
SELECT value FROM vwLogTable WHERE name = 'paramB'