getting ResultSet's values dynamically - java

Is there any way to get ResultSet's values dynamically? here is the code below to make my question clear.
while(rsltSet.next())
{
arr[i][0] = rsltSet.getInt(1)+"";
arr[i][1] = rsltSet.getInt(2)+"";
arr[i][2] = rsltSet.getString(3)+"";
arr[i][3] = rsltSet.getString(4)+"";
arr[i][4] = rsltSet.getString(5)+"";
}
I tried to use code below in a for loop, it gave me an exception which I cannot get the detail of.
for(int j=1;j<columnCount;j++)
arr[i][j] = rslt2.getObject(j)+"";
How can I get the values of ResultSet without specifyinh whether it is integer or string or date?

If you want the type info use the ResultSetMetaData from the ResultSet.getMetaData() call. Otherwise, you can always use getObject(j).toString().

Related

How to view what is inside database JDBC ResultSet in java

I am getting an error saying that some string is missing inside the ResultSet returned from the database. Now I have a problem: how can I see what is inside the ResultSet?
Examples available on google are with explicit methods like getString() or getInt() but thse methods suppose you know what you are looking for. What I actually need - to look what elements are available inside my ResultSet.
Something like when I issue the resultSet.toString() command, and it would show me some kind of map with variable names - is it possible?
EDIT:
If it is useful - below is a piece of code:
public Project mapRow(ResultSet resultSet, int i) throws SQLException {
System.out.println(resultSet.toString());
return new Project(resultSet.getInt("project_id"), resultSet.getString("project_name"),
resultSet.getString("project_description"), new Category(resultSet.getInt("category_id"),
resultSet.getString("category_name")),
resultSet.getString("project_link"), resultSet.getString("project_qa"));
}
Error:
Caused by: org.postgresql.util.PSQLException: The column name category_id was not found in this ResultSet.
The ResultSet contains no element after you execute a statement. To get the first row of information, you need to do rs.next().
Here is a simple iteration through the ResultSet values.
boolean hasValue = false;
while(resultSet.next())
{
hasValue = true;
out.println(resultSet.getString("column_name");
out.println(resultSet.getInt("column_name");
}
if(hasValue)
out.println("Result set has values inside of it");
else out.println("Result set has no values inside of it");
As long as you have some values inside your resultSet variable, you need to iterate it to get the next value. By default, after the query is executed, you have no value inside of it because it might have no value.
Edit:
ResultSetMetaData metaData = resultSet.getMetaData();
int count = metaData.getColumnCount(); //number of column
String columnName[] = new String[count];
for (int i = 1; i <= count; i++)
{
columnName[i-1] = metaData.getColumnLabel(i));
}
This gives you the column names, if this is what you want.
Obtain a ResultSetMetaData from the result set via ResultSet.getMetaData().
The ResultSetMetaData has methods getColumnCount and getColumnName to enumerate the column names.

Java code for getting data from SQL server to MongoDB

I have been struggling with my Mongo-SQL code for a while and still need your help :)
I have a problem while transferring data from an SQL server database to MongoDB. My problem is that I can't do calculations like AVERAGE() or SUM() on my data since I saved them as string in MongoDB. I thought that the numbers would be integers since I got them from my SQL server database where they are stored as integers using the code below. I see now that I use getString() when getting the values. Is that why the numbers are strings in MongoDB? How can I get them as integers? I really want to be able to manipulate them as numbers! Also, some values in SQL server are datetime, so I will need a lot of 'if' statements and different 'get' methods to get all the types right in MongoDB. Does anyone have a good solution to this problem?
StringBuilder orderstatus = new StringBuilder();
orderstatus.append("SELECT * FROM dbo.fact_orderstatus");
PreparedStatement t = connect.prepareStatement(orderstatus.toString());
DBCollection orderstat = db.getCollection("Orderstatus");
ResultSet v = t.executeQuery();
ResultSetMetaData rsm = t.getMetaData();
int column = rsm.getColumnCount();
while (v.next()) {
BasicDBObject orderObj = new BasicDBObject();
for(int x=1; x<column +1; x++){
String namn= rsm.getColumnName(x);
String custNum = (v.getString(x));
if (custNum != null && !custNum.trim().isEmpty()
&& custNum.length() != 0)
orderObj.append(namn, custNum);
}
orderstat.insert(orderObj)
You can utilize the getColumnType() method on your result set.
Since you're using SQL-server I would suggest reading this first:
http://msdn.microsoft.com/en-us/library/ms378668.aspx
This SO question/answer is likely to be helpful too:
Most efficient conversion of ResultSet to JSON?

How to process ResultSet you know has only one record in it

I'm struggling with a homework assignment and am getting hung up on some SQL queries.
My query is interrogating an inventory database for the quantity of some item. The query requests the column with the name quantity_in_stock from the table, given the primary key.
I have initialized some prepared statements. This is the one I'm using here:
stmtFindColumn = Database.getConnection().prepareStatement(String.format("select ? from %s where %s = ?",
INVENTORY_TABLE_NAME, SKU) );
Now a separate method is called. I pass it a static const QTY_IN_STOCK, which is defined as "quantity_in_stock" and the item's SKU number, which is the primary key in the table.
private int getIntegerFromTable(String column, String key) {
int toReturn = 0;
try {
// Complete the prepared statement
stmtFindColumn.setString(1, column);
stmtFindColumn.setString(2, key);
ResultSet result = stmtFindColumn.executeQuery();
toReturn = result.getInt(column);
} catch (SQLException e) {
LOG.error(e.getMessage());
e.printStackTrace();
}
return toReturn;
}
When I run the query I get an sql exception that tells me: Invalid column name quantity_in_stock.
I have tried using a while loop processing result.next() and get the same error. I can't find any examples of how to properly get the results when you know only a single record is being returned.
Help!
EDIT: OK, I've found that part of my problem is I'm not getting a result set, where I should expect one. Any ideas?
UPDATE: I've tested my code, using a garden variety statement and a plain string query instead and it works just fine. So the problem is in my use of the prepared statement. Can someone check if I'm using the ? wildcards correctly? Thanks!
as far as i know, the column name may not be a parameter ...
DarkSquirrel42 is right -- you can't replace the column list of the select using a ? parameter marker. Instead, you can String.format that into place too, for example.
bad:
*select ? from INVENTORY_TABLE_NAME where SKU = ?
good:
select QUANTITY_IN_STOCK from INVENTORY_TABLE_NAME where SKU = ?

Pass varargs from Java code to SQL or PL/SQL

I need to bind at maximum 8 variables. Each one of them could be null.
Is there any recommended way to achieve this? I know that I could simply check for null, but this seems tedious.
Additional details:
I'm going to call this sql from java code. It may be written using JPA 2.0 Criteria API, but most likely it's going to be a native query. The database is Oracle 10g, so I think I could make use of PL/SQL as well.
Edit1:
Maybe the title is a bit misleading, so I'll try to elaborate.
The resulting SQL would be something like:
...
WHERE var1 = :var1
AND var2 = :var2
...
AND var = :var8
Now I need to bind parameters from java code in the way like:
nativeQuery.setParameter("var1", var1)
...
nativeQuery.setParameter("var8", var8)
Some parameters could be null, so there is no need to bind them. But I see no way I can omit them in SQL.
Edit2:
I'm expecting to see SQL or PL/SQL procedure in your answers (if it's ever possible without null checking).
In fact, all of these variables are of the same type. I think it's not possible to find a solution using ANSI SQL, but maybe there are some PL/SQL procedures which allow to work with varargs?
The use of a criteria query is appropriate in this case, because if I understood correctly, you need to construct the SQL query dynamically. If all the variables except var1 are null, the where clause would be
where var1 = :var1
and if all variables except var2 and var5 are non null you would have
where var2 = :var2 and var5 = :var5
Is that right?
If so, then do what you plan to do, and construct the query dynamically using a criteria query. Something like this must be done:
CriteriaBuilder builder = em.getCriteriaBuilder();
Predicate conjunction = builder.conjunction();
if (var1 != null) {
conjunction = builder.and(conjunction,
builder.equal(root.get(MyEntity_.var1),
var1));
}
if (var2 != null) {
conjunction = builder.and(conjunction,
builder.equal(root.get(MyEntity_.var2),
var2));
}
...
criteria.where(conjunction);
You don't specify the type of the objects you want to pass. So in this example I'm considering you will pass Object.
#Test(expected=IllegalArgumentException.class)
public void testMyMethod() {
List<Object> testList = new ArrayList<Object>();
testList.add("1");
testList.add("2");
testList.add(3);
myMethod(testList);
}
public void myMethod(List<Object> limitedList) {
final int MAX_SIZE = 2;
if (limitedList.size() > MAX_SIZE) {
throw new IllegalArgumentException("Size exceeded");
}
//my logic
}
In this example I'm passing the arguments as a List of Objects but you could use array (varargs) or another type of collection if you need to. If the client sends me more than the expected objects it will throw an IllegalArgumentException.
Also if you don't want to throw an exception you could just continue and iterate the list to bind the parameters but using the list size or MAX_SIZE as your limit. For example:
public void myMethod2(List<Object> limitedList) {
final int MAX_SIZE = 2;
int size = MAX_SIZE;
if (limitedList.size() < MAX_SIZE) {
size = limitedList.size();
}
//Iterate through the list
for (int i = 0; i < size; i++) {
Object obj = limitedList.get(i);
//Logic to bind the obj to the criteria.
}
}

How to set list of parameters on prepared statement? [duplicate]

This question already has answers here:
PreparedStatement IN clause alternatives?
(33 answers)
Closed 3 years ago.
i have a list of names e.g.:
List<String> names = ...
names.add('charles');
...
and a statement:
PreparedStatement stmt =
conn.prepareStatement('select * from person where name in ( ? )');
how to do the following:
stmt.setParameterList(1,names);
Is there a workaround? can someone explain why this method is missing?
using: java, postgresql, jdbc3
This question is very old, but nobody has suggested using setArray
This answer might help https://stackoverflow.com/a/10240302/573057
There's no clean way to do this simply by setting a list on the PreparedStatement that I know of.
Write code that constructs the SQL statement (or better replaces a single ? or similar token) with the appropriate number of questions marks (the same number as in your list) and then iterate over your list setting the parameter for each.
this method is missing due to type erasure the parameter type of the List is lost at runtime. Therefore the need to add several methods arires: setIntParameters, setLongParameters, setObjectParameters, etc
For postgres 9 I have used this approach:
jdbcTemplate.query(getEmployeeReport(), new PreparedStatementSetter() {
#Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setTimestamp(1, new java.sql.Timestamp(from.getTime()));
ps.setTimestamp(2, new java.sql.Timestamp(to.getTime()));
StringBuilder ids = new StringBuilder();
for (int i = 0; i < branchIds.length; i++) {
ids.append(branchIds[i]);
if (i < branchIds.length - 1) {
ids.append(",");
}
}
// third param is inside IN clause
// Use Types.OTHER avoid type check while executing query
ps.setObject(3, ids.toString(), **Types.OTHER**);
}
}, new PersonalReportMapper());
In case the questions' meaning is to set several params in a single call...
Because the type validation is already defined in a higher level, I think the only need is for setObject(...).
Thus, a utility method can be used:
public static void addParams(PreparedStatement preparedStatement, Object... params) throws SQLException {
for (int i = 0; i < params.length; i++) {
Object param = params[i];
preparedStatement.setObject(i+1, param);
}
}
Usage:
SqlUtils.addParams(preparedStatement, 1, '2', 3d);
Feel free converting this to a Java 8 lambda :)
I was reviewing code this morning and one of my colleagues had a different approach, just pass the parameter using setString("name1','name2','name3").
Note: I skipped the single quote at the beginning and end because these are going to be added by the setString.
After examining various solutions in different forums and not finding a good solution, I feel the below hack I came up with, is the easiest to follow and code. Note however that this doesn't use prepared query but gets the work done anyway:
Example: Suppose you have a list of parameters to pass in the 'IN' clause. Just put a dummy String inside the 'IN' clause, say, "PARAM" do denote the list of parameters that will be coming in the place of this dummy String.
select * from TABLE_A where ATTR IN (PARAM);
You can collect all the parameters into a single String variable in your Java code. This can be done as follows:
String param1 = "X";
String param2 = "Y";
String param1 = param1.append(",").append(param2);
You can append all your parameters separated by commas into a single String variable, 'param1', in our case.
After collecting all the parameters into a single String you can just replace the dummy text in your query, i.e., "PARAM" in this case, with the parameter String, i.e., param1. Here is what you need to do:
String query = query.replaceFirst("PARAM",param1); where we have the value of query as
query = "select * from TABLE_A where ATTR IN (PARAM)";
You can now execute your query using the executeQuery() method. Just make sure that you don't have the word "PARAM" in your query anywhere. You can use a combination of special characters and alphabets instead of the word "PARAM" in order to make sure that there is no possibility of such a word coming in the query. Hope you got the solution.
Other method :
public void setValues(PreparedStatement ps) throws SQLException {
// first param inside IN clause with myList values
ps.setObject(1 , myList.toArray(), 2003); // 2003=array in java.sql.Types
}

Categories