I want to print my rows count at the end, But it shows 1
public void showRecords() {
try {
Statement st1 = con.createStatement();
ResultSet result1 = st1.executeQuery("select * from mytable");
while (result1.next()) {
System.out.println(result1.getString(1) + " " + result1.getString(2));
}
ResultSet rs1 = st1.executeQuery("select count(*) from mytable");
int rows = rs1.last() ? rs1.getRow() : 0;
System.out.println("Number of rows is: "+ rows); //print 1
} catch (SQLException sqle) {
System.out.println("Can not excute sql statement");
sqle.printStackTrace();
}
}
Output:
...
Number of rows is: 1
Output: ... Number of rows is: 1
That's absolutely correct because the ouput of a count query like
select count(*) from mytable
would only contain a single row containing the total number of rows. For you to now retrieve that count you should make use of the Resultset's getter methods as usual.
int rows = rs1.getInt(1);
To retrieve the count the way you wanted to; use the same approach with your first query
ResultSet result1 = st1.executeQuery("select * from mytable");
int rows = result1.last() ? result1.getRow() : 0;
System.out.println("Number of rows is: "+ rows); // should print the count
The count(*) does not have a column name (or only a "generated" one that you might not know). Therefor you need to get the value by column index.
Additionally you need to call next() on the ResultSet in order to be able to obtain the value:
ResultSet rs1 = st1.executeQuery("select count(*) from mytable");
int rows = 0;
if (rs1.next() {
rows = rs1.getInt(1);
}
System.out.println("Number of rows is: "+ rows); //print 1
Selecting the count from a RecoredSet always returns a value of 1, i.e. the record containing the result of the query. You want
ResultSet rs1 = st1.executeQuery("select count(*) from mytable");
if (rs1.next()) {
int rows = rs1.getInt("COUNT")
}
You must read the value from the rowcount query, as it is a normal query. Like
rows = rs1.getInt(1);
I've written a blog post about retrieving query metadata without extra roundtrip, which is something people typically do to paginate their data. I really recommend you don't re-run your queries all the time just to count stuff. A simple approach would be to use window functions, which are now supported in a lot of SQL dialects:
SELECT *, count(*) OVER () FROM mytable
Of course, since you're using low level JDBC API to iterate your ResultSet, why not just count things in the client at that point? E.g.
try (ResultSet rs = s.executeQuery("select * from mytable")) {
int i = 0;
while (rs.next()) {
System.out.println(rs.getString(1) + " " + rs.getString(2));
i++;
}
System.out.println("Number of rows is: " + i);
}
Related
i'm inserting multiple rows into a table using a single insert statement. The table has an auto increment field as the primary key.
Like so: INSERT INTO MyTable VALUES (?,?,?,?),(?,?,?,?),(?,?,?,?),(?,?,?,?)
StringJoiner sj = new StringJoiner(",");
for(int i=0;i<salesmen.size();i++)
sj.add("(?,?,?,?)");
sql.append("INSERT INTO MyTable ");
sql.append("VALUES ");
sql.append(sj.toString());
try(PreparedStatement statement = connection.prepareStatement(sql.toString(),Statement.RETURN_GENERATED_KEYS)){
int i = 1;
for(Salesman salesman : salesmen){
statement.setDate(i++, DateUtil.toSqlDate(date));
statement.setString(i++, salesman.getName());
statement.setInt(i++, salesman.getWeeklyTargetCustomerId());
statement.setInt(i++, salesman.getCycle());
}
statement.executeUpdate();
ResultSet generatedKeys = statement.getGeneratedKeys();
while(generatedKeys.next()) {
log.info("generated key: " + generatedKeys.getLong(1)); //only prints 1 id
}
}
catch(SQLException e){
log.info("(!!) SQL Exception in Execution: " + e.getMessage());
log.info("\n\n" + sql.toString() + "\n");
}
When i call getGeneratedKeys(), it returns a ResultSet with only the id of the last row inserted, and not all of the rows. If i insert 50 rows, how do i obtain a resultset with 50 generated keys?
Although it's an old question, I hope it helps someone.
PreparedStatement pre = connection.prepareStatement("SQL", PreparedStatement.RETURN_GENERATED_KEYS);
for(Salesman salesman: salesmen) {
pre.setString(i++, ...);
pre.setString(i++, ...);
....
pre.addBatch(); // Add this
}
pre.executeBatch(); // Add this
ResultSet rs = pre.getGeneratedKeys();
while(rs.next()) {
int id = rs.getInt(1); // This should contain the id of the inserts in order.
}
I have a scenario here I need to compare 2 database tables using java
First Database table has
id Name Salary
1 ABC 1000
2 XYZ 2000
3 LMN 3000
Second Database Table has
id Name Salary
4 PQR 5000
2 XYZ 2000
1 ABC 4000
3 LMN 2500
I had used list to compare but is there any other way to compare 1st table with the 2nd table using selenium java.
I want the output to be
Second table has 4 rows while 1 table has 3 rows (or vice versa)
1st table LMN salary is 3000 and second table LMN salary is 2500
I would do the requested comparison in SQL directly. This will be faster. There are a couple of ways to do this depending on the results you need.
Since you are using Microsoft SQL you can retrieve the number of rows in the requested format by doing something like this:
SELECT 'The FirstTable has ' + cast((SELECT count(*) from FirstTable) as varchar(50)) + ' records, while the SecondTable has ' + cast((SELECT count(*) from SecondTable) as varchar(50)) + ' records';
For getting the differences between the tables you can do something like this:
SELECT * FROM FirstTable
UNION
SELECT * FROM SecondTable
EXCEPT
SELECT * FROM FirstTable
INTERSECT
SELECT * FROM SecondTable;
Then you can take ResultSet and compare the entries like this:
while (resultSet.next())
{
int id= rs.getInt("id");
String name= rs.getString("name");
int firstTableSalary = rs.getInt("salary");
rs.next();
int secondTableSalary = rs.getInt("salary");
console.log(String.format("The first table salary is %d, while the second table salary is %d, name=%s, id=%d", firstTableSalary, secondTableSalary, name, id);
}
I prepared here a fiddle for checking the SQLs.
Getting the salary differences is easier with SQL
String query = "select t1.name,t1.salary t1_salary, t2.salary t2_salary" +
" from table1 t1, table2 t2 "+
" where t1.id=t2.id and t1.name=t2.name and t1.salary!=t2.salary";
//this will give you a result set of all the names and salaries from the two tables
//where the salaries differ.
Connection conn = ...
try (Statement stmt = conn.createStatement()){
ResultSet rs = stmt.executeQuery(query);
while (rs.next()){
String name = rs.getString(1);
Integer t1Salary = rs.getInt(2);
Integer t2Salary = rs.getInt(3);
//do something with these values
}
rs.close();
Similarly, capture the table lengths with queries
int t1Length = 0;
int t2Length = 0;
rs = stmt.executeQuery("select count(*) from table1");
while (rs.next()){
t1Length = rs.getInt(1);
}
rs.close();
rs = stmt.executeQuery("select count(*) from table2");
while (rs.next()){
t2Length = rs.getInt(1);
}
rs.close();
//do something with the lengths
}
conn.close();
I am passing the following query to a ResultSet object:
String query = "SELECT COUNT( DISTINCT KEY ), SOURCE FROM MY_TBL\n" +
"GROUP BY SOURCE\n" +
"ORDER BY SOURCE";
I want to capture the counts I am getting for each SOURCE and sum them into a total. How can I capture these counts via ResultSet since COUNT isn't a column name in the ResultSet and I don't think I can return it's value via rs.getInt("COUNT")?
getInt is overloaded, use index (an int) instead of a column name:
rs.getInt(1); // the first column is 1
Try having alias
String query = "SELECT COUNT( DISTINCT KEY ) AS COUNT, SOURCE FROM MY_TBL\n" +
"GROUP BY SOURCE\n" +
"ORDER BY SOURCE";
I Think it is better to use
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * from Customer");
ResultSetMetaData rsmd = rs.getMetaData();
int numCols = rsmd.getColumnCount();
I think "getColumnCount" retinto number of column in a table instead of number of rows...
i have used a select command in my java program and stored its value in the result set. now while looping in the resultset i want to use a select command which will select the first 5 lines of the resultset and insert into other table. for the second time, it should select the next 5 lines and insert into the table. and for the third time, so on..
Statement s = connection.createStatement();
s.executeQuery("Select * from table1");
ResultSet res = s.getResultSet();
while(res.next()){
// here i want to select the first 5 lines of the result set and insert in the second table
}
Statement s = connection.createStatement();
s.executeQuery("Select * from table1");
ResultSet res = s.getResultSet();
while(res.next()){
// here i want to select the first 5 lines of the result set and insert in the second table
while(res.next() && (res.getRow()%5) !=0){
//select from this table
//call insert method(what selected)
}
}
I would suggest changing your query using LIMIT and using a PreparedStatement. Something like:
SELECT * FROM table1 LIMIT ?,?
This has a couple of advantages:
You are not fetching everything in one shot - can be sometimes a performance benefit if you've a lot many rows to deal with in your table
You can change pre-define the number of elements that you want to fetch in every single batch
So your code will look something like this:
PreparedStatement ps = null;
ResultSet rs = null;
final int FETCH_LIMIT = 5; //number of elements to fetch per batch
final int BATCH_LIMIT = 3; //number of batches you would want
int currentRows = 0;
try{
ps = connection.prepareStatement("SELECT * FROM table1 LIMIT ?,?");
for(int currentBatch = 0; currentBatch < BATCH_LIMIT; currentBatch++){
ps.clearParameters();
ps.setInt(1, currentRows);
ps.setInt(2, currentRows + FETCH_LIMIT);
try{
rs = ps.executeQuery();
while(rs.next()){
// do your work
}
}catch(Exception exe){
//manage exception
}finally{
//manage resultset
}
currentRows += FETCH_LIMIT;
}
}catch(Exception exe){
//Handle your exception
}
finally{
//Manage your resources
}
Please add a falg and use that is it
int i=0;
while(res.next() && i< 5){
//select from this table
//call insert method(what selected)
i++;
}
Create another insert query dynamically inside the while loop and execute it outside the while loop
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.");
}
}