Mybatis: How can I get the first element from the passed parameter? - sql

Given that my parameterType is an ArrayList, is it possible to get the first element from that list and use it in the where clause ?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="db">
<select id="selectFlag" resultType="java.lang.Boolean" parameterType="java.util.ArrayList">
select TOP 1 'true' from customers where id = ???
</select>
</mapper>

If your query uses one id, why are you sending a list and then picking the first one for the query?
Change your parameterType to an int (or whatever type the id has), don't send a list. This is a simple approach that also conveys the information that you are only retrieving data based on a single id. Your condition then changes to something like:
where id = #{id}
If you must absolutely send an ArrayList (for whatever reason) then MyBatis supports OGNL expressions so something like this should work:
where id = #{list[0]}
Unfortunately MyBatis lacks on the documentation side, so you can find out about things like this only by looking at the source code.

Related

Extract data from XML string in Hive Table without using XPath

I am trying to use a view to extract a string(value) from a large XML string that sits in a single column in a hive table. I need to get the associated FOO_STRING_VALUE for COMPANY_ID, SALE_IND, and CLOSING_IND.
<Message>
<Header>
<FOO_STRING>
<FOO_STRING_NAME>COMPANY_ID</FOO_STRING_NAME>
<FOO_STRING_VALUE>44-1235</FOO_STRING_VALUE>
</FOO_STRING>
<FOO_STRING>
<FOO_STRING_NAME>SALE_IND</FOO_STRING_NAME>
<FOO_STRING_VALUE>Y</FOO_STRING_VALUE>
</FOO_STRING>
<FOO_STRING>
<FOO_STRING_NAME>CLOSING_IND</FOO_STRING_NAME>
<FOO_STRING_VALUE>Y</FOO_STRING_VALUE>
</FOO_STRING>
</Header>
</Message>
The XML file can have up to 50 "FOO_STRINGS" and there is no guarantee in what order they will be in so I can not use XPATH unless I have 50 xpath_string calls for each Name/Value pair and matched them up later. I am using xpath like this .....
xpath_string(xml_txt, '/Message/Header/FOO_STRING[1]/FOO_STRING_VALUE') AS String_Val_1
xpath_string(xml_txt, '/Message/Header/FOO_STRING[2]/FOO_STRING_VALUE') AS String_Val_2
xpath_string(xml_txt, '/Message/Header/FOO_STRING[3]/FOO_STRING_VALUE') AS String_Val_3
However, if the order changes than it doesn't work. I'm wondering if there is a quick way to get to find the FOO_STRING_NAME needed the and get the corresponding Value using regexp_extract() or some other way? I am not familiar with Regex so any help or suggestions would be helpful, Thank you a ton
" if the order changes than it doesn't work "
Don't use position, then.
xpath_string(xml_txt, '/Message/Header/FOO_STRING[FOO_STRING_NAME="COMPANY_ID"]/FOO_STRING_VALUE') AS String_Val_1
xpath_string(xml_txt, '/Message/Header/FOO_STRING[FOO_STRING_NAME="SALE_IND"]/FOO_STRING_VALUE') AS String_Val_2
xpath_string(xml_txt, '/Message/Header/FOO_STRING[FOO_STRING_NAME="CLOSING_IND"]/FOO_STRING_VALUE') AS String_Val_3

Export SQL XML field to grid [duplicate]

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'

EclipseLink MOXy #XmlPath is returning the incorrect data for contains

I am attempting to unmarshal an XML data stream with EclipseLink MOXy with an XPath using the contains function.
When I apply the sample XPath directly to the sample XML data stream I get the correct value returned (Ref_number_1). However, when I unmarshal this using MOXy, the value that is set for refNumber1 is "Ref_number_2".
Does MOXy not support this type of XPath? It would appear that it at least is understanding it because it's not throwing an error, just setting the wrong value.
Anyone have any experience with this sort of thing? Know of a better approach?
Thanks for any help.
Marshal code:
String s = //xml stream from restful service (see xml example below);
StringReader sr = new StringReader(s);
ReferenceNumber refNum = (ReferenceNumber)marshaller.unmarshal(
new StreamSource(sr));
Member annotation:
#XmlPath("Header/ReferenceNumbers/ReferenceNumber[contains(ReferenceNumberType, \"REF_NUMBER_TYPE_1\")]/ReferenceNumber/text()")
private String refNumber1;
XML data:
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<Header>
<ReferenceNumbers>
<ReferenceNumber>
<ReferenceNumber>Ref_number_1</ReferenceNumber>
<ReferenceNumberType>REF_NUMBER_TYPE_1</ReferenceNumberType>
</ReferenceNumber>
<ReferenceNumber>
<ReferenceNumber>Ref_number_2</ReferenceNumber>
<ReferenceNumberType>REF_NUMBER_TYPE_2</ReferenceNumberType>
</ReferenceNumber>
</ReferenceNumbers>
</Header>
</Document>
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
Currently MOXy does not support XPaths of that form. Currently a conditional check must be on an attribute contained within the element such as (see: http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html).
#XmlPath("personal-info/name[#type='first']/text()")
String firstName;
I have entered the following bug so that we improve the validation that we do on our #XmlPath annotation:
http://bugs.eclipse.org/397101
I am also interested in the use case described in your question. Would you mind entering an enhancement requires against the MOXy component for this:
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink

Get an XML Element via XPath when attributes are irrelevant

I'm looking for a way to receive a XML Element (the id of an entry) from a YouTube feed (e.g. http://gdata.youtube.com/feeds/api/users/USERNAME/uploads).
The feed looks like this:
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:yt="http://gdata.youtube.com/schemas/2007" gd:etag="W/"DUcFQncyfCp7I2A9WhVUFE4."">
<id>tag:youtube.com,2008:user:USERNAME:uploads</id>
<updated>2012-05-19T14:16:53.994Z</updated>
...
<entry gd:etag="W/"DE8NSX47eCp7I2A9WhVUFE4."">
<id>tag:youtube.com,2008:video:MfPpj7f6Jj0</id>
<published>2012-05-18T13:30:38.000Z</published>
...
I want to get the first tag in entry (tag:youtube.com, 2008 ...).
After googling for some hours and looking through the GDataXML wiki, I'm clueless because neither XPath nor GData could deliver the right element.
My first guess is, they can't ignore the attributes in the feed and entry tags.
A solution using XPath would be great, but one in Objective-C is equally welcome.
You might be having an issue trying to get XPath to work because of the default namespace.
If you just want the first tag in entry, you can use this:
/*/*[name()='entry']/*[1]
If you want the first id specifically, you can use this:
/*/*[name()='entry']/*[name()='id'][1]
Also if you can use XPath 2.0, you can skip the predicate entirely and use * for the namespace prefix:
/*/*:entry/*:id[1]

How to get required XML element from not well formed XML data in SQL server

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