I have a SQL query with a simple SELECT statement, FOR XML AUTO, ELEMENTS.
This is a sample text result in SQL Management Studio:
> XML_F52E2B61-18A1-11d1-B105-00805F49916B
> -------------------------------------------------------------------------------- <row><CompanyID>0</CompanyID><Company>0
> </Company><GlCode>00-1010</GlCode><GlYear>2009</GlYear><BeginYearBalance>0.00</BeginYearBalance><ClosingBalPer1>50251640.00</ClosingBalPer1><ClosingBalPer2>45141985.00</ClosingBalPer2><ClosingBalPer3>43603485.00</C
> lPer7><ClosingBalPer8>0.00</ClosingBalPer8><ClosingBalPer9>0.00</ClosingBalPer9><ClosingBalPer10>0.00</ClosingBalPer10><ClosingBalPer11>0.00</ClosingBalPer11><ClosingBalPer12>0.00</ClosingBalPer12><ClosingBalPer13>0.00</ClosingBalPer13><ClosingBalPer14>0.0
> BalPer1><ClosingBalPer2>20000.00</ClosingBalPer2><ClosingBalPer3>0.00</ClosingBalPer3><ClosingBalPer4>0.00</ClosingBalPer4><ClosingBalPer5>0.00</ClosingBalPer5><ClosingBalPer6>0.00</ClosingBalPer6><ClosingBalPer7>0.00</ClosingBalPer7><ClosingBalPer8>0.00</
> alPer14>
It creates the familiar structure of <row> element for each record, with an element for each column.
However, this is what comes back when I run the node in Flowgear:
<Result>
<Table>
<XML_F52E2B61-18A1-11d1-B105-00805F49916B><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1010</GlCode><GlYear>2009</GlYear><BeginYearBalance>0.00</BeginYearBalance><ClosingBalPer1>50251640.00</ClosingBalPer1><ClosingBalPer2>45141985.00</ClosingBalPer2><ClosingBalPer3>43603485.00</ClosingBalPer3><ClosingBalPer4>37602854.06</ClosingBalPer4><ClosingBalPer5>30477670.97</ClosingBalPer5><ClosingBalPer6>27131030.91</ClosingBalPer6><ClosingBalPer7>26489572.00</ClosingBalPer7><ClosingBalPer8>24508174.38</ClosingBalPer8><ClosingBalPer9>25107606.36</ClosingBalPer9><ClosingBalPer10>24838327.11</ClosingBalPer10><ClosingBalPer11>28456828.16</ClosingBalPer11><ClosingBalPer12>3205488.90</ClosingBalPer12><ClosingBalPer13>3205488.90</ClosingBalPer13><ClosingBalPer14>3205488.90</ClosingBalPer14><ClosingBalPer15>0.00</ClosingBalPer15></row><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1010</GlCode><GlYear>2010</GlYear><BeginYearBalance>3205488.90</BeginYearBalance><ClosingBalPer1>69904850.41</ClosingBalPer1><ClosingBalPer2>70035845.09</ClosingBalPer2><ClosingBalPer3>69751854.18</ClosingBalPer3><ClosingBalPer4>76699659.70</ClosingBalPer4><ClosingBalPer5>64868593.99</ClosingBalPer5><ClosingBalPer6>63343067.84</ClosingBalPer6><ClosingBalPer7>67160186.41</ClosingBalPer7><ClosingBalPer8>66030723.36</ClosingBalPer8><ClosingBalPer9>67336905.21</ClosingBalPer9><ClosingBalPer10>67363017.56</ClosingBalPer10><ClosingBalPer11>67275039.96</ClosingBalPer11><ClosingBalPer12>64310025.92</ClosingBalPer12><ClosingBalPer13>64310025.92</ClosingBalPer13><ClosingBalPer14>64310025.92</ClosingBalPer14><ClosingBalPer15>0.00</ClosingBalPer15></row><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1010</GlCode><GlYear>2011</GlYear><BeginYearBalance>64310025.92</BeginYearBalance><ClosingBalPer1>63333898.71</ClosingBalPer1><ClosingBalPer2>63334486.71</ClosingBalPer2><ClosingBalPer3>0.00</ClosingBalPer3><ClosingBalPer4>0.00</ClosingBalPer4><ClosingBalPer5>0.00</ClosingBalPer5><ClosingBalPer6>0.00</ClosingBalPer6><ClosingBalPer7>0.00</ClosingBa</XML_F52E2B61-18A1-11d1-B105-00805F49916B>
</Table>
<Table>
<XML_F52E2B61-18A1-11d1-B105-00805F49916B>lPer7><ClosingBalPer8>0.00</ClosingBalPer8><ClosingBalPer9>0.00</ClosingBalPer9><ClosingBalPer10>0.00</ClosingBalPer10><ClosingBalPer11>0.00</ClosingBalPer11><ClosingBalPer12>0.00</ClosingBalPer12><ClosingBalPer13>0.00</ClosingBalPer13><ClosingBalPer14>0.00</ClosingBalPer14><ClosingBalPer15>0.00</ClosingBalPer15></row><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1020</GlCode><GlYear>2009</GlYear><BeginYearBalance>0.00</BeginYearBalance><ClosingBalPer1>20000.00</ClosingBalPer1><ClosingBalPer2>20000.00</ClosingBalPer2><ClosingBalPer3>20000.00</ClosingBalPer3><ClosingBalPer4>20000.00</ClosingBalPer4><ClosingBalPer5>20000.00</ClosingBalPer5><ClosingBalPer6>20000.00</ClosingBalPer6><ClosingBalPer7>20000.00</ClosingBalPer7><ClosingBalPer8>20000.00</ClosingBalPer8><ClosingBalPer9>20000.00</ClosingBalPer9><ClosingBalPer10>20000.00</ClosingBalPer10><ClosingBalPer11>20000.00</ClosingBalPer11><ClosingBalPer12>20000.00</ClosingBalPer12><ClosingBalPer13>20000.00</ClosingBalPer13><ClosingBalPer14>20000.00</ClosingBalPer14><ClosingBalPer15>0.00</ClosingBalPer15></row><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1020</GlCode><GlYear>2010</GlYear><BeginYearBalance>20000.00</BeginYearBalance><ClosingBalPer1>20000.00</ClosingBalPer1><ClosingBalPer2>20000.00</ClosingBalPer2><ClosingBalPer3>20000.00</ClosingBalPer3><ClosingBalPer4>20000.00</ClosingBalPer4><ClosingBalPer5>20000.00</ClosingBalPer5><ClosingBalPer6>20000.00</ClosingBalPer6><ClosingBalPer7>20000.00</ClosingBalPer7><ClosingBalPer8>20000.00</ClosingBalPer8><ClosingBalPer9>20000.00</ClosingBalPer9><ClosingBalPer10>20000.00</ClosingBalPer10><ClosingBalPer11>20000.00</ClosingBalPer11><ClosingBalPer12>20000.00</ClosingBalPer12><ClosingBalPer13>20000.00</ClosingBalPer13><ClosingBalPer14>20000.00</ClosingBalPer14><ClosingBalPer15>0.00</ClosingBalPer15></row><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1020</GlCode><GlYear>2011</GlYear><BeginYearBalance>20000.00</BeginYearBalance><ClosingBalPer1>20000.00</Closing</XML_F52E2B61-18A1-11d1-B105-00805F49916B>
</Table>
<Table>
<XML_F52E2B61-18A1-11d1-B105-00805F49916B>BalPer1><ClosingBalPer2>20000.00</ClosingBalPer2><ClosingBalPer3>0.00</ClosingBalPer3><ClosingBalPer4>0.00</ClosingBalPer4><ClosingBalPer5>0.00</ClosingBalPer5><ClosingBalPer6>0.00</ClosingBalPer6><ClosingBalPer7>0.00</ClosingBalPer7><ClosingBalPer8>0.00</ClosingBalPer8><ClosingBalPer9>0.00</ClosingBalPer9><ClosingBalPer10>0.00</ClosingBalPer10><ClosingBalPer11>0.00</ClosingBalPer11><ClosingBalPer12>0.00</ClosingBalPer12><ClosingBalPer13>0.00</ClosingBalPer13><ClosingBalPer14>0.00</ClosingBalPer14><ClosingBalPer15>0.00</ClosingBalPer15></row><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1030</GlCode><GlYear>2009</GlYear><BeginYearBalance>0.00</BeginYearBalance><ClosingBalPer1>15000.00</ClosingBalPer1><ClosingBalPer2>30000.00</ClosingBalPer2><ClosingBalPer3>30000.00</ClosingBalPer3><ClosingBalPer4>30000.00</ClosingBalPer4><ClosingBalPer5>30000.00</ClosingBalPer5><ClosingBalPer6>30000.00</ClosingBalPer6><ClosingBalPer7>30000.00</ClosingBalPer7><ClosingBalPer8>30000.00</ClosingBalPer8><ClosingBalPer9>30000.00</ClosingBalPer9><ClosingBalPer10>30000.00</ClosingBalPer10><ClosingBalPer11>30000.00</ClosingBalPer11><ClosingBalPer12>30000.00</ClosingBalPer12><ClosingBalPer13>30000.00</ClosingBalPer13><ClosingBalPer14>30000.00</ClosingBalPer14><ClosingBalPer15>0.00</ClosingBalPer15></row><row><CompanyID>0</CompanyID><Company>0 </Company><GlCode>00-1030</GlCode><GlYear>2010</GlYear><BeginYearBalance>30000.00</BeginYearBalance><ClosingBalPer1>30000.00</ClosingBalPer1><ClosingBalPer2>30000.00</ClosingBalPer2><ClosingBalPer3>30000.00</ClosingBalPer3><ClosingBalPer4>30000.00</ClosingBalPer4><ClosingBalPer5>30000.00</ClosingBalPer5><ClosingBalPer6>30000.00</ClosingBalPer6><ClosingBalPer7>30000.00</ClosingBalPer7><ClosingBalPer8>30000.00</ClosingBalPer8><ClosingBalPer9>30000.00</ClosingBalPer9><ClosingBalPer10>30000.00</ClosingBalPer10><ClosingBalPer11>30000.00</ClosingBalPer11><ClosingBalPer12>30000.00</ClosingBalPer12><ClosingBalPer13>30000.00</ClosingBalPer13><ClosingBalPer14>30000.00</ClosingB</XML_F52E2B61-18A1-11d1-B105-00805F49916B>
</Table>
The Node is further splitting the result into what seems to be fixed-length <Table> elements. where the 2nd Table node contains the balance of text from the 1st Table element.
This results in VERY different XML, and I don't know how to deal with this, seemingly non-structured, XML in the next Flowgear Node (my XSLT transformation)
Please help...why is this happening and how can I make it stop?
When you are using an XML query, you need to tick the XmlQuery property on the Node.
SQL returns a very different response for XML queries and Flowgear needs to be told to parse it accordingly.
See http://developers.flowgear.net/kb/Node:SQL_Query for more details.
Related
I have the following XML:
<Main>
<ResultOutput>
<Name>TEST1</Name>
<Value>D028</Value>
</ResultOutput>
<ResultOutput>
<Name>TEST2</Name>
<Value>Accept</Value>
</ResultOutput>
<ResultOutput>
<Name>TEST3</Name>
<Value />
</ResultOutput>
</Main>
What I want is to get the value of the <value> tag in SQL.
Basically want to say get <value> where <Name> has the value of TEST1, as an example
This is what I have at the moment, but this depends on the position of the XML tag:
XMLResponse.value(Main/ResultOutput/Value)[5]', nvarchar(max)')
The best way to do this is not to put extra where .value clauses, but to do it directly in XQuery.
Use [nodename] to filter by a child node, you can even nest such predicates. text() gets you the inner text of the node:
XMLResponse.value('(/Main/ResultOutput[Name[text()="TEST1"]]/Value/text())[1]', 'nvarchar(max)')
Below is an example using the sample XML in your question. You'll need to extend this to add namespace declarations and the proper xpath expressions that may be present in your actual XML as your query attempt suggests.
SELECT ResultOutput.value('Value[1]', 'nvarchar(100)')
FROM #xml.nodes('Main/ResultOutput') AS Main(ResultOutput)
WHERE ResultOutput.value('Name[1]', 'nvarchar(100)') = N'TEST1';
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'
I have a table with a mix of escaped and non-escaped XML. Of course, the data I need is escaped. For example, I have:
<Root>
<InternalData>
<Node>
<ArrayOfComment>
<Comment>
<SequenceNo>1</SequenceNo>
<IsDeleted>false</IsDeleted>
<TakenByCode>397</TakenByCode>
</Comment>
</ArrayOfComment>
</Node>
</InternalData>
</Root>
As you can see, the data in the Node tag is all escaped. I can use a query to obtain the Node data, but how can I convert it to XML in SQL so that it can be parsed and broken up? I'm pretty new to using XML in SQL, and I can't seem to find any examples of this.
Thanks
You have not given enough information about your end goal, but this will get you very close. FYI - You had two missing ; both after comment>
declare #xml xml
set #xml = '
<Root>
<InternalData>
<Node>
<ArrayOfComment>
<Comment>
<SequenceNo>1</SequenceNo>
<IsDeleted>false</IsDeleted>
<TakenByCode>397</TakenByCode>
</Comment>
</ArrayOfComment>
</Node>
</InternalData>
</Root>
'
select convert(xml, n.c.value('.', 'varchar(max)'))
from #xml.nodes('Root/InternalData/Node/text()') n(c)
Output
<ArrayOfComment>
<Comment>
<SequenceNo>1</SequenceNo>
<IsDeleted>false</IsDeleted>
<TakenByCode>397</TakenByCode>
</Comment>
</ArrayOfComment>
The result is an XML column that you can put into a variable or cross-apply into directly to get data from the XML fragment.
Your best bet might be to look into a HTML Decoding UDF. I did a quick search and found this one:
http://www.andreabertolotto.net/Articles/HTMLDecodeUDF.aspx
You may want to modify it so it only decodes > and <. The one above seems to go above and beyond your needs.
UPDATE
#Cyberkiwi's solution seems to be a bit cleaner. I will leave this up in case the version of SQL Server you are running doesn't support his solution.
In my SQL 2008 database table, I have one column name AUTHOR that contains XML data. The XML is not well formed and has data like below
<Author>
<ID>172-32-1176</ID>
<LastName>White</LastName>
<FirstName>Johnson</FirstName>
<Address>
<Street>10932 Bigge Rd.</Street>
<City>Menlo Park</City>
<State>CA</State>
</Address>
</Author>
Some XML have all of above data and some have just one tag.
<ID>172-32-1176</ID>
I want to write query that returns me a column as identiry.
I tried using AUTHOR.query('data(/Author/ID)') as identity but it fails when XML does not have Author node.
Thanks,
Vijay
Have you tried something like /Author/ID|/ID ? i.e. try for the first scenario, and with no match, the second ?
(note that the | operator is a set union operator, as described here)
In case that nothing "certain" can be maintained about the XML, except that a unique ID element contains the required identity value, then the following XPath expression selects the ID element:
//ID
With xml like:
<a>
<b>
<c>1</c>
<c>2</c>
</c>3</c>
</b>
I'm trying to create an xpath expression (for a postgresql query) that will return if is a particular value and not that is all three values. What I currently have (which does not work) is:
select * from someTable where xpath ('//uim:a/text()', job, ARRAY[ ARRAY['uim','http://www.cmpy.com/uim'] ])::text[] IN (ARRAY['1','3']);
If I try with ARRAY['1'] this will not return any values but with ARRAY['1','2','3'] it will return all three.
How can I select based on a single element in a sequence?
Thanks.
If you're asking how to get the value of a 1 or more XML elements within your XML segment the easiest way is likely to simply utilize a custom SQL CLR library and XPath analysis from within it to assemble and return whatever information you desire. At least that would be my approach.