How to get multiple lines from mysql - java

I'm trying to fetch from mysql table multiple lines data, for example:
1 car
2 shop
3 dress
But for now it's only fetch the first line.
My code so far:
case "2":
ResultSet rsl2 = stmt.executeQuery("SELECT payments FROM payment;" );
while(rsl2.next()) {
String sqlRes = rsl2.getString("payments");
System.out.println(sqlRes);
if (sqlRes != null) {
System.out.println("OK");
return sqlRes;
}
}

You may either append all your data to the sqlRes variable
sqlRes += rsl2.getString("payments");
and change your if statement to
if (sqlRes == null)
return sqlRes;
or place your return statement after the while loop. Either way, you should append the data in the sqlRes variable if you finally want the returned value to hold all the values in your DB.

Related

Java.sql.ResultSet bug for rs.next()

The SQL code works and next() function outputs true or false but is not accepted by the if (condition).
boolean status = res.next();
if (res.next()) {
System.out.println("first");
}
if (status) {
System.out.println("second");
}
The code above has the same semantics but the one using the method next() doesn’t work.
If there is only one record in the resultset, status will be true but the next attempt of res.next() will return false. Thus, the following code will output only second.
boolean status = res.next();
if (res.next()) {
System.out.println("first");
}
if (status) {
System.out.println("second");
}
If there are two records in the resultset, you will get both, first and second as the output.
To summarize,
Output when there is only one record in the resultset
second
Output when there are two records in the resultset
first
second
What you did making the result set to move to the second row because you call next() twice
, You can check this one:
if (res.next()) {
System.out.println(“first”);
} else {
System.out.println(“second”);
}

using ResultSet when row value from database is NULL

When querying the database directly, result is NULL, now Im using ResultSet to check if result is NULL, do something else, if result is not NULL, print the result: This my COde:
if(rs4 != null) {
while(rs4.next()) {
String ad =rs4.getString("number");
System.out.println(ad);
}
}
else{
System.out.println("ZERO ENTRIES");
}`
Database row value is NULL,since there is no row returned from my query so definitely i expect the else statement to run, but now the if statement is still being excecuted and prints null
What you see as NULL when querying the DB directly is the value of the column number, not the value of the row.
so, that's why you get a non-null row with a NULL value in number column in your ResultSet.
You can use something like:
if (!resultSet.isBeforeFirst() ) {
System.out.println("No data");
}
Or:
if (!resultSet.next() ) {
System.out.println("no data");
}
I finally found a way to go around it. Using rs.getInt() this will return 0 whenever row value is NULL and return new row value , whenever there is a row found.
This solved it :-)
while(rs.next())
{
// using rs.getInt() will return zero when row value from your query is NULL
int i = rs.getInt("number");
if(i<0) //check if zero
{
// When result is NULL i =0
System.out.println("your value");
}else{
//When there are rows found from database i > 0
String ad=rs.getString("number");
System.out.println(ad);
}
}`

JPA Criteria Query API and order by null last

My problem is null values must be last order by statement. My code snipshot below. I use javax persistance criteria builder. My query complicated.
import javax.persistence.criteria.CriteriaBuilder;
public Predicate getSomePredicate() {
Predicate predicate = cb.conjunction();....
...predicate.getExpressions().add(cb.and(cb.or(cb.and(v1, v2), cb.and(s1, s2))));
EOrderByType orderType = EOrderByType.values()[orderBy]
;
switch (orderType) {
case PRICE: cq.where(predicate).orderBy(cb.asc(root.get("price")));
break;
case PRICE_HIGH_TO_LOW: cq.where(predicate).orderBy(cb.desc(root.get("price")));
break;
case CONSUPTION: cq.where(predicate).orderBy(cb.desc(root.get("consume")));
break;
default:
break;
}
return cq.getRestriction();
}
How to achieve order by price null last with criteria builder ?
Hi I almost search all internet pages and then find a solution, you can write switch case order by part. like below: to order by desc if price is null, price value is 1000000, and to order by asc if price is null, price value is 0. if you want these, you can write expression like below.
EOrderByType orderType = EOrderByType.values()[orderBy];
Expression<Object> queryCase = cb.selectCase().when(cb.isNull(root.get("price")), 100000000).otherwise(root.get("price"));
Direction dir = Direction.ASC;
switch (orderType) {
case UCUZDAN_PAHALIYA:
queryCase = cb.selectCase().when(cb.isNull(root.get("price")), 100000000).otherwise(root.get("price"));
break;
case PAHALIDAN_UCUZA:
queryCase = cb.selectCase().when(cb.isNull(root.get("price")), 0).otherwise(root.get("price"));
dir = Direction.DESC;
break;
}
cq.where(predicate).orderBy(direction( cb, queryCase, dir));
This is a bit of an extension to katsu's answer to his own question. I was trying to find a solution to being able to sort most of the columns of a table where some columns are allowed to have null values. I wanted to sort the null values in front of the lowest non-null values when sorting in ascending order and after the lowest non-null values when sorting in descending order. In other words, pretty much the opposite of the (Oracle's) default behavior.
I found other methods that might do this, but this one didn't require me to go outside of Hibernate and JPA 2 persistence, but still get the results I wanted. This is a snippet of code taken from my actual code, but consolidated in one spot and with some names changed. Any syntax, compilation-type errors you see are probably due to that.
// sortByColumn is a String containing the Hibernate version of the column name, which had
// been assigned as the ID of the table header column of the column by which we are sorting.
// sortAscending is a Boolean object containing Boolean.TRUE if we are to sort in ascending
// order or Boolean.FALSE or null if we are to sort in descending order. This may seem a
// bit odd, but in the case we need this for, the default sort column is a release date and
// reverse chronological order is the most useful in that case.
// Also defined are: CriteriaQuery<SoftwareVersion> criteriaQuery and
// CriteriaBuilder criteriaBuilder by the typical means.
final Root<SoftwareVersion> softwareVersionRoot =
criteriaQuery.from(SoftwareVersion.class);
private static final String EMPTY_STRING = "";
if (sortByColumn != null && sortByColumn.trim().length() > 0) {
Order sortOrder;
Expression<String> sortColumnExpression;
if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileLength.getName()) ||
sortByColumn.equalsIgnoreCase(SoftwareVersion_.releaseTimestamp.getName())) {
// The two non-String fields (exposed to the user) that we don't need to have the
// lower() function operate upon.
sortColumnExpression = oemSoftwareVersionRoot.get(sortByColumn);
} else {
// We use the lower() function to enforce case insensitive sorting on the columns we
// show to the user, which are all Strings except as noted above.
Expression<String> rootExpression = oemSoftwareVersionRoot.get(sortByColumn);
sortColumnExpression = criteriaBuilder.lower(rootExpression);
}
// The columns for installation file name, installation file length and release timestamp
// are just three of the columns that we allow the user to sort by. However, these three
// may have null values in the database, and require some special handling.
if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileLength.getName()) ||
sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileName.getName()) ||
sortByColumn.equalsIgnoreCase(SoftwareVersion_.releaseTimestamp.getName())
) {
Expression<Object> queryCase;
if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.installationFileName.getName())) {
// Installation file name is a (case insensitive) String
queryCase = criteriaBuilder.selectCase().when(
criteriaBuilder.isNull(sortColumnExpression),
StringUtil.EMPTY_STRING).otherwise(sortColumnExpression);
} else if (sortByColumn.equalsIgnoreCase(SoftwareVersion_.releaseTimestamp.getName())) {
// Release timestamp is a database timestamp
LocalDateTime dateTime = LocalDateTime.of(1970,1,1,0,0);
// Equivalent to Unix epoch time. Note month is 1-12, not 0-11
queryCase = criteriaBuilder.selectCase().when(
criteriaBuilder.isNull(sortColumnExpression),
Timestamp.valueOf(dateTime)).otherwise(sortColumnExpression);
} else {
// Installation file length is a Long (or BigDecimal) computed when the file is uploaded.
// The user can't set or change it, but can sort by it.
queryCase = criteriaBuilder.selectCase().when(
criteriaBuilder.isNull(sortColumnExpression),
Long.valueOf(0)).otherwise(sortColumnExpression);
}
if (asc != null && asc.booleanValue()) {
sortOrder = criteriaBuilder.asc(queryCase);
} else {
sortOrder = criteriaBuilder.desc(queryCase);
}
} else {
if (asc != null && asc.booleanValue()) {
sortOrder = criteriaBuilder.asc(sortColumnExpression);
} else {
sortOrder = criteriaBuilder.desc(sortColumnExpression);
}
}
criteriaQuery.orderBy(sortOrder);
}

java jdbc executeQuery() working but execute() not (multiple resultsets) [duplicate]

I'm calling a Sybase stored procedure that returns multiple resultsets through JDBC.
I need to get a specific result set that has a column named "Result"
This is my code :
CallableStatement cs = conn.prepareCall(sqlCall);
cs.registerOutParameter(1, Types.VARCHAR);
cs.execute();
ResultSet rs=null;
int count = 1;
boolean flag = true;
while (count < 20000 && flag == true) {
cs.getMoreResults();
rs = cs.getResultSet();
if (rs != null) {
ResultSetMetaData resultSetMetaData = rs.getMetaData();
int columnsCount = resultSetMetaData.getColumnCount();
if (resultSetMetaData.getColumnName(1).equals("Result")) {
// action code resultset found
flag = false;
// loop on the resultset and add the elements returned to an array list
while (rs.next()) {
int x = 1;
while (x <= columnsCount) {
result.add(rs.getString(x));
x++;
}
}
result.add(0, cs.getString(1));
}
}
count++;
}
What happens here is that cs.getMoreResults returns a lot of null resultsets till it reaches the target one. I can't use cs.getMoreResults as loop condition because it returns false for null resultsets.
I put a fixed number to end the loop in condition the wanted result set wasn't returned to prevent it from going into infinite loop. It worked fine but I don't think this is right.
I think the null resultsets returned from the assignment in Sybase select #variable = value
Has anyone faced this before?
You are misinterpreting the return value of getMoreResults(). You are also ignoring the return value of execute(), this method returns a boolean indicating the type of the first result:
true: result is a ResultSet
false : result is an update count
If the result is true, then you use getResultSet() to retrieve the ResultSet, otherwise getUpdateCount() to retrieve the update count. If the update count is -1 it means there are no more results. Note that the update count will also be -1 when the current result is a ResultSet. It is also good to know that getResultSet() should return null if there are no more results or if the result is an update count (this last condition is why you get so many null values).
Now if you want to retrieve more results, you call getMoreResults() (or its brother accepting an int parameter). The return value of boolean has the same meaning as that of execute(), so false does not mean there are no more results!
There are only no more results if the getMoreResults() returns false and getUpdateCount() returns -1 (as also documented in the Javadoc)
Essentially this means that if you want to correctly process all results you need to do something like below:
boolean result = stmt.execute(...);
while(true) {
if (result) {
ResultSet rs = stmt.getResultSet();
// Do something with resultset ...
} else {
int updateCount = stmt.getUpdateCount();
if (updateCount == -1) {
// no more results
break;
}
// Do something with update count ...
}
result = stmt.getMoreResults();
}
My guess is that you are getting a lot of update counts before you get the actual ResultSet.
I am not really familiar with Sybase, but its cousin SQL Server has the 'annoying' feature to return update counts from stored procedures if you don't explicitly put SET NOCOUNT ON; at the start of the stored procedure.
NOTE: Part of this answer is based on my answer to Execute “sp_msforeachdb” in a Java application

Null resultsets when calling Sybase stored procedure through JDBC

I'm calling a Sybase stored procedure that returns multiple resultsets through JDBC.
I need to get a specific result set that has a column named "Result"
This is my code :
CallableStatement cs = conn.prepareCall(sqlCall);
cs.registerOutParameter(1, Types.VARCHAR);
cs.execute();
ResultSet rs=null;
int count = 1;
boolean flag = true;
while (count < 20000 && flag == true) {
cs.getMoreResults();
rs = cs.getResultSet();
if (rs != null) {
ResultSetMetaData resultSetMetaData = rs.getMetaData();
int columnsCount = resultSetMetaData.getColumnCount();
if (resultSetMetaData.getColumnName(1).equals("Result")) {
// action code resultset found
flag = false;
// loop on the resultset and add the elements returned to an array list
while (rs.next()) {
int x = 1;
while (x <= columnsCount) {
result.add(rs.getString(x));
x++;
}
}
result.add(0, cs.getString(1));
}
}
count++;
}
What happens here is that cs.getMoreResults returns a lot of null resultsets till it reaches the target one. I can't use cs.getMoreResults as loop condition because it returns false for null resultsets.
I put a fixed number to end the loop in condition the wanted result set wasn't returned to prevent it from going into infinite loop. It worked fine but I don't think this is right.
I think the null resultsets returned from the assignment in Sybase select #variable = value
Has anyone faced this before?
You are misinterpreting the return value of getMoreResults(). You are also ignoring the return value of execute(), this method returns a boolean indicating the type of the first result:
true: result is a ResultSet
false : result is an update count
If the result is true, then you use getResultSet() to retrieve the ResultSet, otherwise getUpdateCount() to retrieve the update count. If the update count is -1 it means there are no more results. Note that the update count will also be -1 when the current result is a ResultSet. It is also good to know that getResultSet() should return null if there are no more results or if the result is an update count (this last condition is why you get so many null values).
Now if you want to retrieve more results, you call getMoreResults() (or its brother accepting an int parameter). The return value of boolean has the same meaning as that of execute(), so false does not mean there are no more results!
There are only no more results if the getMoreResults() returns false and getUpdateCount() returns -1 (as also documented in the Javadoc)
Essentially this means that if you want to correctly process all results you need to do something like below:
boolean result = stmt.execute(...);
while(true) {
if (result) {
ResultSet rs = stmt.getResultSet();
// Do something with resultset ...
} else {
int updateCount = stmt.getUpdateCount();
if (updateCount == -1) {
// no more results
break;
}
// Do something with update count ...
}
result = stmt.getMoreResults();
}
My guess is that you are getting a lot of update counts before you get the actual ResultSet.
I am not really familiar with Sybase, but its cousin SQL Server has the 'annoying' feature to return update counts from stored procedures if you don't explicitly put SET NOCOUNT ON; at the start of the stored procedure.
NOTE: Part of this answer is based on my answer to Execute “sp_msforeachdb” in a Java application

Categories