Select array fields from Hive table using JDBC - java

I have a Hive table which has column with array data type. I am using JDBC to select rows from the table.
SELECT col1 FROM hive_table WHERE condition = 'condition'
After receiving the resultset, I am using res.getArray() method for the specific array field while looping through resultset.
Array arrayCol = res.getArray(1);
This is throwing a "Method not supported" error. Is it valid to use getArray() method for such queries executed on Hive table?

Unfortunately, no. You can see getArray() method is not implemented in ResultSet class for Hive JDBC. The actual class name is HiveBaseResultSet and the source code is located here.
Depends on what type of values the array holds, a client program need to decode its value by itself. For example, a column of type array<string> is encoded as a single String object like `["VALUE1","VALUE2",...,"VALUEN"]'. And we can use getString() method and freely re-construct any object of type Array<String> or List<String>.

You can loop though the result set and add the column values to arraylist in java. See example below assuming that your table column is of String type.
List<String> list = new ArrayList<String>();
while (res.next()) {
list.add( res.getString(1));
}

Related

Dynamic Oracle Type not visible in Java

I have an oracle function that I use to update some data into the database from Java.
The Function:
FUNCTION addFunc (
contact_id IN NUMBER,
contact_distrib_list IN contact_array
)
RETURN VARCHAR2;
The array type is declared in the package as
TYPE contact_array IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
Now,
I am trying to call this Function from my Java code.
ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("contact_array", sqlConnection);
But, when i try to do the above it complains that the type is not recognized.
java.sql.SQLException: invalid name pattern: contact_array
I tried all the ways to supply a sql name here. I tried the schema name.package name.array name etc. But still the same error.
Am I incorrectly defining the type in oracle?
Is there any other way of connecting using Java JDBC?
If you want to pass a PL/SQL index-by table (also known as an associative array) to a stored procedure, you will need to use Oracle extensions to JDBC. You cannot use ArrayDescriptor with index-by tables.
In particular, you will need to use the OracleCallableStatement.setPlsqlIndexTable method, for example:
((OracleCallableStatement)callableStatement).setPlsqlIndexTable(
3, data, data.length, data.length, Types.VARCHAR, 100);
I'm assuming that the index-by table is parameter number 3 and that data contains the array of Strings you wish to pass as the contents of the table. The number 100 is the length of the elements within the collection.

Retrieve the entire row with ResultSet of a CQL query

I have set up a Cassandra connection through Java driver. And I want to retrieve an entire row as a collection. I want to get rid of using getString() or getInt() always. When I give a query saying select all columns in the users table using CQL. the entire result should be sent to a collection rather than a string. How do I achieve this?
I have done the following to retrieve the columns. It gives me the proper results. But I want to retrieve the entire row as a collection.
Outside the for loop I want to retrieve these fields as one object. How do I do this??
String name=null;
String age=null;
ResultSet results = session.execute("SELECT * FROM admin.users");
for (Row row : results) {
name=row.getString("firstname");
age=row.getString("age");
System.out.println("name::"+name);
System.out.pintl("age::"+age);
}
If you want to obtain all fields in a collection you could use getMap(..) function and you will get a Map with keys and values.
On the other hand, check new object Mapping API since version 2.1 and you can map a class directly from ResultSet with annotations in your entity class.

Building an Array from an ResultSet?

I'm pretty new to the whole SQL and Java thing, but here I'm actually really confused.
I have a method which is called by invoking a few array parameters, as following
Method(String[], int, int[], int[])
I'm doing a ResultSet to check to see if there are any rows available where there is an ID match for the searched item.
ResultSet group = statement.executeQuery("SELECT * FROM `circulation` WHERE `ItemID` = "+itemID);
However, I'm completely stumped here on how to construct the method.
The String[], and int[] parameters are what is stored in the database, while the standard int parameter is the itemID. I have no idea how to go about doing this to call the Method correctly.
Darn, I thought I was doing good, too.
Arguments are normally used to provide information to the method being called. To get information from the method being called, you normally use a return value.
Your method seems to search rows in a database table named circulation for a given item ID. The item ID should thus be an argument. The found rows should be a returned value. The signature of the method should thus be:
Circulation[] findByItemId(int itemId);
Or better, using collections instead of arrays:
List<Circulation> findByItemId(int itemId);
What is Circulation? It's a class that represents what a row of the circulation table contains. So if the table contains an ID, a name and an item ID, this class would look like
public class Circulation {
private int id;
private String name;
private int itemId;
// constructor, getters, and other useful methods omitted for brevity
}
Your findByItemId() method will thus create an empty list of Circulation, then iterate over the rows of the result set, construct a Circulation instance for each row, and add the instance to the list. And then it will return that list.
Finally, you're using concatenation to build a SQL query taking parameters. This is dangerous. You should use a prepared statement instead. Read the tutorial about them.
Take a look at Apache commons-dbutils. It is a simple wrapper around JDBC and lets you convert your resultsets into any standard datastructures
You can use function
rs.getArray()
with columnName or ColumnLabel.
But this function return objects array and you can cast it to Integer and String.

ClassCastException after executing stored procedure in java

I am getting ClassCastException after executing stored procedure, written in Oracle, using spring-jdbc.
Here is the code snippet that is giving issue, here data is the List that i get from procedure:
for(Object[] obj :data){
}
Below is the error:
java.lang.ClassCastException: oracle.jdbc.driver.OracleResultSetImpl cannot be cast to [Ljava.lang.Object
I think the issue is after getting the OUT cursor from the procedure How to use it in Java code i.e. how to extract values from it?
Unfortunately, searching the web didn't give me any solutions. What can I try next?
data is not a list (or array) of arrays. It is an implementation of the interface oracle.jdbc.driver.OracleResultSet. So you cannot iterate over it using a for-each loop.
It also implements ResultSet, which defines the method next().
Therefore you can iterate over data using a while-loop:
while (data.next()){
Object obj = data.getObject(col);
// do somthing with obj
}
The method next() moves the cursor to the next row.
col can either be the column index or label.
Here you can find an example on using ResultSet.

How do you get the type from a cursor?

The javadocs indicate that android.database.Cursor has a getType(int) method. However, when I try to call this method, Eclipse gives me an error saying no method exists. What gives?
What version of Android are you targeting? The getType() method applies only to v3.0 and later.
EDIT: Assuming you're targeting pre v3.0 versions of Android then a possible 'hack' to discover the type of each column within a table would be to query the sqlite_master table to find the CREATE data.
SELECT sql FROM sqlite_master
It's pretty nasty but if you really need to find the type then you could extend SQLiteCursor and add your own getType(int columnIndex) method.
You could perform a one-off query to the sqlite_master table when the cursor first accesses a table then parse the CREATE statement from the sql column and store the 'types' in an int[].
In the getType(int columnIndex) you would simply return the value of your int[] based on columnindex.
As I said, bit of a hack but it would work.
As you can store any type of data in (nearly) every SQLite field. Looking up the data type in sqlite_master and by using the pragma command is not a safe method. You can get the type of the fields using a query like this:
select Field1, typeof(Field1), Field2, typeof(Field2) from MyTable
This statement returns both the value of the fields and their types which might / might not change from record to record.

Categories

Resources