Why ResultSet returning 0 value after execution? - java

i guess i'm too tired or what.. Can't see anything bad here.
String select = "SELECT project_id FROM project WHERE project_key = ?";
PreparedStatement preparedStatement1 = con.prepareStatement(select);
preparedStatement1.setString(1, project_key);
ResultSet rs = preparedStatement1.executeQuery();
int project_id = 0;
while(rs.next()) {
project_id = rs.getInt("project_id");
}
System.out.println(project_id);
the problem is why project_id returning me 0?
P.S. In database, i do have my project table fully inserted, and yes, i double checked value that are asked.

Change the code to be
while(rs.next()) {
int project_id = rs.getInt("project_id");
System.out.println(project_id);
}
I guess you will see no values (if there is a problem with the project_key)
Or many values the last one will be zero!

Try the following code to see if the result set returns any value
rs.first();
System.out.println(rs.getInt("project_id"));
If you don't see any value it means that the problem has to do with the query. Nothing is returned and the set is empty.
(I was going to comment this but I don't have enough reputation)

Related

getting the result of sql command in java [duplicate]

This question already has an answer here:
java.sql.sqlexception column not found
(1 answer)
Closed 4 years ago.
i need to get the last id entered in my data base witch is AUTO_INCREMENT so i did this
String Var = "SELECT MAX(id) FROM goupe ; ";
ResultSet vari=st.executeQuery(Var);
while(vari.next()){
nombre = vari.getInt("id");}
String sql = "INSERT INTO Student(name,famillyname,email,password,module,speciality,card,id_goupe)VALUES('"+name+"','"+familly+"','"+email+"','"+pass+"','"+module+"','"+specialite+"','"+card+"','"+nombre+"');";
st.execute(sql);
but i had this problem Column 'id' not found.
so what should i do to have it right .
I have to say, there are a couple of really easy things you can do to greatly improve your code.
If your latest ID is generated elsewhere, then embed the query directly into the statement such that you don't need to go get it. That will reduce the risk of a race condition.
Use PreparedStatements. Let me ask you this question: What do you suppose is going to happen if one of your user's name is O'Ryan?
Since your code is just a snip, I also will only provide a snip:
int index = 1;
String sql = "INSERT INTO Student(name,famillyname,email,password,module,speciality,card,id_goupe)" +
"VALUES(?,?,?,?,?,?,?,(SELECT MAX(id) FROM goupe));";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(index++, name);
ps.setString(index++, familyname);
ps.setString(index++, email);
ps.setString(index++, password);
ps.setString(index++, module);
ps.setString(index++, speciality);
ps.setString(index++, card);
int rows = ps.executeUpdate();
if(rows == 1) {
System.out.println("Successfully inserted row");
}
When you execute the query SELECT MAX(id) FROM goupe;, then in the returned table, the column name no longer remains as id.
So, the best approach is to provide a name for the column like below:
SELECT MAX(id) AS maxid FROM goupe;
Then, you can get the value using:
vari.getInt("maxid")

Get the number of rows from ResultSet

I am trying to get the number in ResultSet that I am getting from my query as in the code below. The query retrieves the number 5. How can I get this number from ResultSet?
Code:
String sql_count_stop = "select count(*) FROM behaviour where mac = ? ";
PreparedStatement preparedCount = con.prepareStatement(sql_count_stop);
preparedCount.setString(1, macD);
ResultSet rsCount = preparedCount.executeQuery();
while(rsCount.next()){
}
You can modify your query to
"SELECT count(*) AS totalCount FROM behaviour WHERE mac = ? ";
and then use,
macId= rsCount.getInt("totalCount");
Or use position rsCount.getInt(1) and you don't need a column alias.
Also since there will be only one row, if(rsCount.next()) is just as good as while, and in my opinion more clearly shows this logic will only execute once.
You can modify you SQL statement to: (added AS 'countMacs')
select count(*) as 'countMacs' FROM behaviour where mac = ?
Then get a value
while(rsCount.next()){
int count = rsCount.getInt("countMacs");
}

Assigning resultset column value to a variable for use in another SQL Statement?? Java

I am creating a data centric webservice in Java for deployment to Glassfish. All of my methods so far are working correctly except for one.
I am attempting to assign a value from a result set to a variable to use in another SQL statement as per the below code. I am not sure if its possible, or if perhaps my SQL is wrong, but any ideas would be appreciated.
ResultSet rset1 = stmt1.executeQuery("SELECT *
FROM WorkOrder
WHERE WorkOrderID = '"+workOrderID+"'");
Integer custID = rset1.getInt(3);
ResultSet rset2 = stmt2.executeQuery("SELECT *
FROM Customer
WHERE CustID = '"+custID+"'");
Integer quoteID = rset1.getInt(2);
ResultSet rset3 = stmt3.executeQuery("SELECT *
FROM Quote
WHERE QuoteID = '"+quoteID+"'");
What you posted can and should be done in a single query - less complex, and less [unnecessary] traffic back & forth with the database:
SELECT q.*
FROM QUOTE q
WHERE EXISTS (SELECT NULL
FROM CUSTOMER c
JOIN WORKORDER wo ON wo.custid = c.custid
WHERE c.quoteid = q.quoteid
AND wo.workorderid = ?)
The reason this didn't use JOINs is because there'd be a risk of duplicate QUOTE values if there's more than one workorder/customer/etc related.
Additionally:
Numeric data types (quoteid, custid, etc) should not be wrapped in single quotes - there's no need to rely on implicit data type conversion.
You should be using parameterized queries, not dynamic SQL
You foget to invoke ResultSet.next().
if(rset1.next())
{
Integer custID = rset1.getInt(3);
....
}
The note provided by OMG Ponies was really important to take note of, but does not really answer the question. AVD was also correct. I've cleaned it up a bit and included prepared statements. Please use prepared statements. They will help you sleep at night.
PreparedStatement pstmt1 = con.prepareStatement(
"SELECT * FROM WorkOrder WHERE WorkOrderID = ?");
PreparedStatement pstmt2 = con.prepareStatement(
"SELECT * FROM Customer WHERE CustID = ?");
PreparedStatement pstmt3 = con.prepareStatement(
"SELECT * FROM Quote WHERE QuoteID = ?");
pstmt1.setInt(1, workOrderId)
ResultSet rset1 = pstmt1.executeQuery();
// test validity of rset1
if(rset1.next()) {
pstmt2.setInt(1, rset1.getInt(3))
ResultSet rset2 = pstmt2.executeQuery();
// test validity of rset2
if(rset2.next()) {
pstmt3.setInt(1, rset1.getInt(2))
ResultSet rset3 = pstmt3.executeQuery();
}
}

How can NULL and regular values be handled without using different prepared statements?

Consider this simple method:
public ResultSet getByOwnerId(final Connection connection, final Integer id) throws SQLException {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?");
statement.setObject(1, id);
return statement.executeQuery();
}
The example method is supposed to select everything from some table where a column's value matches, which should be simple.
The ugly detail is that passing NULL for the id will result in an empty ResultSet, regardless how many rows there are in the DB because SQL defines NULL as not euqaling anyting, not even NULL.
The only way to select those rows I know of is using a different where clause:
SELECT * FROM MyTable WHERE MyColumn IS NULL
Unfortunately the only way to make the method work properly in all cases seems to be to have two entirely different execution pathes, one for the case where the id argument is null and one for regular values.
This is very ugly and when you have more than one column that can be nulled can get very messy quickly. How can one handle NULL and normal values with the same code path/statement?
I haven't tried this, but the way to send nulls to preparedStatements is to use the setNull() option
PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?");
if ( id == null)
statement.setNull(1, java.sql.Types.INTEGER);
else
statement.setObject(1, id);
return statement.executeQuery();
EDIT : Thanks for the responses #Gabe and #Vache. It does not look like there is an easy way to do this other than taking a more longwinded approach to dynamically create the preparedstatment.
Something like this should work --
String sql = " SELECT * FROM MyTable WHERE " + (id==null)?"MyColumn is null":"MyColumn = ?" ;
PreparedStatement statement = connection.prepareStatement(sql);
if ( id != null)
statement.setObject(1, id);
return statement.executeQuery();
You could use a query like this:
select * from MyTable where
case when ?1 is null then MyColumn is null else MyColumn = ?1
But it reuses the same parameter, so I don't know whether the syntax I've proposed (?1) will work.

How do I get the size of a java.sql.ResultSet?

Shouldn't this be a pretty straightforward operation? However, I see there's neither a size() nor length() method.
Do a SELECT COUNT(*) FROM ... query instead.
OR
int size =0;
if (rs != null)
{
rs.last(); // moves cursor to the last row
size = rs.getRow(); // get row id
}
In either of the case, you won't have to loop over the entire data.
ResultSet rs = ps.executeQuery();
int rowcount = 0;
if (rs.last()) {
rowcount = rs.getRow();
rs.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element
}
while (rs.next()) {
// do your standard per row stuff
}
Well, if you have a ResultSet of type ResultSet.TYPE_FORWARD_ONLY you want to keep it that way (and not to switch to a ResultSet.TYPE_SCROLL_INSENSITIVE or ResultSet.TYPE_SCROLL_INSENSITIVE in order to be able to use .last()).
I suggest a very nice and efficient hack, where you add a first bogus/phony row at the top containing the number of rows.
Example
Let's say your query is the following
select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where ...blahblah...
and your output looks like
true 65537 "Hey" -32768 "The quick brown fox"
false 123456 "Sup" 300 "The lazy dog"
false -123123 "Yo" 0 "Go ahead and jump"
false 3 "EVH" 456 "Might as well jump"
...
[1000 total rows]
Simply refactor your code to something like this:
Statement s=myConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String from_where="FROM myTable WHERE ...blahblah... ";
//h4x
ResultSet rs=s.executeQuery("select count(*)as RECORDCOUNT,"
+ "cast(null as boolean)as MYBOOL,"
+ "cast(null as int)as MYINT,"
+ "cast(null as char(1))as MYCHAR,"
+ "cast(null as smallint)as MYSMALLINT,"
+ "cast(null as varchar(1))as MYVARCHAR "
+from_where
+"UNION ALL "//the "ALL" part prevents internal re-sorting to prevent duplicates (and we do not want that)
+"select cast(null as int)as RECORDCOUNT,"
+ "MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR "
+from_where);
Your query output will now be something like
1000 null null null null null
null true 65537 "Hey" -32768 "The quick brown fox"
null false 123456 "Sup" 300 "The lazy dog"
null false -123123 "Yo" 0 "Go ahead and jump"
null false 3 "EVH" 456 "Might as well jump"
...
[1001 total rows]
So you just have to
if(rs.next())
System.out.println("Recordcount: "+rs.getInt("RECORDCOUNT"));//hack: first record contains the record count
while(rs.next())
//do your stuff
int i = 0;
while(rs.next()) {
i++;
}
I got an exception when using rs.last()
if(rs.last()){
rowCount = rs.getRow();
rs.beforeFirst();
}
:
java.sql.SQLException: Invalid operation for forward only resultset
it's due to by default it is ResultSet.TYPE_FORWARD_ONLY, which means you can only use rs.next()
the solution is:
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
[Speed consideration]
Lot of ppl here suggests ResultSet.last() but for that you would need to open connection as a ResultSet.TYPE_SCROLL_INSENSITIVE which for Derby embedded database is up to 10 times SLOWER than ResultSet.TYPE_FORWARD_ONLY.
According to my micro-tests for embedded Derby and H2 databases it is significantly faster to call SELECT COUNT(*) before your SELECT.
Here is in more detail my code and my benchmarks
The way of getting size of ResultSet, No need of using ArrayList etc
int size =0;
if (rs != null)
{
rs.beforeFirst();
rs.last();
size = rs.getRow();
}
Now You will get size, And if you want print the ResultSet, before printing use following line of code too,
rs.beforeFirst();
It is a simple way to do rows-count.
ResultSet rs = job.getSearchedResult(stmt);
int rsCount = 0;
//but notice that you'll only get correct ResultSet size after end of the while loop
while(rs.next())
{
//do your other per row stuff
rsCount = rsCount + 1;
}//end while
String sql = "select count(*) from message";
ps = cn.prepareStatement(sql);
rs = ps.executeQuery();
int rowCount = 0;
while(rs.next()) {
rowCount = Integer.parseInt(rs.getString("count(*)"));
System.out.println(Integer.parseInt(rs.getString("count(*)")));
}
System.out.println("Count : " + rowCount);
theStatement=theConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet theResult=theStatement.executeQuery(query);
//Get the size of the data returned
theResult.last();
int size = theResult.getRow() * theResult.getMetaData().getColumnCount();
theResult.beforeFirst();
I checked the runtime value of the ResultSet interface and found out it was pretty much a ResultSetImpl all the time. ResultSetImpl has a method called getUpdateCount() which returns the value you are looking for.
This code sample should suffice:
ResultSet resultSet = executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()
I realize that downcasting is generally an unsafe procedure but this method hasn't yet failed me.
Today, I used this logic why I don't know getting the count of RS.
int chkSize = 0;
if (rs.next()) {
do { ..... blah blah
enter code here for each rs.
chkSize++;
} while (rs.next());
} else {
enter code here for rs size = 0
}
// good luck to u.
I was having the same problem. Using ResultSet.first() in this way just after the execution solved it:
if(rs.first()){
// Do your job
} else {
// No rows take some actions
}
Documentation (link):
boolean first()
throws SQLException
Moves the cursor to the first row in this ResultSet object.
Returns:
true if the cursor is on a valid
row; false if there are no rows in the result set
Throws:
SQLException - if a database access error occurs; this method is called on a closed result set or the result set type is TYPE_FORWARD_ONLY
SQLFeatureNotSupportedException - if the JDBC driver does not support
this method
Since:
1.2
Easiest approach, Run Count(*) query, do resultSet.next() to point to the first row and then just do resultSet.getString(1) to get the count. Code :
ResultSet rs = statement.executeQuery("Select Count(*) from your_db");
if(rs.next()) {
int count = rs.getString(1).toInt()
}
Give column a name..
String query = "SELECT COUNT(*) as count FROM
Reference that column from the ResultSet object into an int and do your logic from there..
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, item.getProductId());
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
int count = resultSet.getInt("count");
if (count >= 1) {
System.out.println("Product ID already exists.");
} else {
System.out.println("New Product ID.");
}
}

Categories

Resources