get size of ResultSet by using SELECT COUNT(*) - java

I want to retrieve all the data from database, and at the same time, I want to know how many rows of data I get. And this is my SQL:
rs = s.executeQuery("SELECT COUNT(*), * FROM tblUser");
Is this a valid SQL statement? and after I retrieved all the data, how to set them into different variables? For example, I have a column called UserIDin the database, I can simply get it by using rs.getString('UserID'), but how to get the result of the COUNT(*)?

Your SQL is not valid. The ANSI standard way to do what you want uses window functions:
select count(*) over () as total_cnt,
u.*
from tblUser u;
This adds a new column to every row -- which seems to be what you want. There are other mechanisms, depending on the underlying database for doing this.

The results you request are not interrelated, so run two queries:
rs1 = s.executeQuery("SELECT COUNT(*) FROM tblUser");
rs2 = s.executeQuery("SELECT * FROM tblUser");
and retrieve the values (one only for rs1) the usual way.

You can do this to count the rows in resultset
String query = "Select * from tblUser";
rs = s.executeQuery(query);
public int getCount(ResultSet rs) {
int rows = 0;
while(rs.next()) {
i++;
}
return i;
}
This way you can get the resultset as well as count

Since you are already accessing the recordset within VBA probably the simplest was to return the count of the record set is to:
rs = s.executeQuery("SELECT * FROM tblUser");
If Not rs.EOF Then
' Important: You must move to the last record to
' obtain the count of the full recordset
rs.MoveLast
rsCount = rs.RecordCount
' Remember to Return to the First Record so that you can
' continue to use the recordset
rs.MoveFirst
End If

An alternative if your RDBMS doesn't support window functions
rs = s.executeQuery("SELECT B.cnt, U.*
FROM tblUser U,
(SELECT count(*) cnt FROM tblUser) B");

Related

Unknown column '$a' in 'where clause'

i want to fetch data from database by using a variable string.it shows error
"Unknown column '$a' in 'where clause'"
String a=request.getParameter("from");
ResultSet resultset= statement.executeQuery("select * from flight where f = $a") ;
If you want to use the value of the a variable where you have $a, you need to use a prepared statement and fill it in:
String a = request.getParameter("from");
PreparedStatement ps = connection.prepareStatement( // Create a prepared statement
"select * from flight where f = ?" // Using ? for where the
); // parameter goes
ps.setString(1, a); // Fill in the value (they
// start a 1, oddly)
ResultSet resultset = ps.executeQuery(); // Execute the query
Note that even though it's a string, you don't put quotes around the ?. The PreparedStatement handles that for you at the DB driver level, in a way that's safe from SQL injection.

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");
}

alternative to jdbc resultset rs.next()

I have a first resultset within which I have to iterate through userids and for each userid, I have to perform several select count(*)'s all of which return single valued outputs. If you haven't understood what I said, please follow the pseudo code below:
ResultSet rs = stmt.executeQuery("select userid from tablename");
while(rs.next()){
String userid = rs.getString("userId");
ResultSet rs1 = stmt.executeQuery("select count(*) as cnt1 from xxx.... where userId = "+userId);
if(rs1.next())
String count1 = rs1.getString("cnt1");
rs1.close();
ResultSet rs2 = stmt.executeQuery("select count(*) as cnt2...");
if(rs2.next())
String count2 = rs2.getString("cnt2");
rs2.close();
....
rs10.close();
Since this is inefficient, I was hoping to get past Resultset each time by writing some sort of direct query to retrieve each different count like
String cnt1 = stmt.executeQuery("select count(*) as noE from useractiontable where curr_action='edit'" + " and userId = " + userId).getString("noE");
I know something like this cannot be done without using rs.next() each time. Is prepare statement the way to go? Is there another way? Appreciate any pointers in this regard.
You can use group by to retrieve all the user with count(*)
ResultSet rs = stmt.executeQuery("select userid,count(*) from tablename group by userid");
I suspect that you can do all the DB work in one query and then just have one result set to read. It would be much more efficient and much cleaner code. I am thinking something like:
select userid, count(*) as cnt
from tablename t inner join othertablename ot on t.userid = ot.userid
group by userid
If you have other columns in tablename that you want, you would add them to the select and to the group-by. For example:
select userid, username, count(*) as cnt
from tablename t inner join othertablename ot on t.userid = ot.userid
group by userid, username
The above queries will not return userid's with a count of zero. If you want the ones with zeros, use an outer join (and make the counting logic deal with the null case):
select userid, username, isnull(count(ot.userid), 0) as cnt
from tablename t left outer join othertablename ot on t.userid = ot.userid
group by userid, username

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();
}
}

Parameterized Oracle SQL query in Java?

I've been trying to figure out why the following code is not generating any data in my ResultSet:
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "Waterloo");
ResultSet rs = prepStmt.executeQuery();
On the other hand, the following runs properly:
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = 'Waterloo' ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
ResultSet rs = prepStmt.executeQuery();
The data type for SCHOOL is CHAR (9 Byte). Instead of setString, I also tried:
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
String school = "Waterloo";
Reader reader = new CharArrayReader(school.toCharArray());
prepStmt.setCharacterStream(1, reader, 9);
prepStmt.setString(1, "Waterloo");
ResultSet rs = prepStmt.executeQuery();
I'm completely stuck on what to investigate next; the Eclipse debugger says the SQL query doesn't change even after setString or setCharacterStream. I'm not sure if it's because setting parameters isn't working, or if the debugger simply can't pick up changes in the PreparedStatement.
Any help will be greatly appreciated, thanks!
I think the problem is that your datatype is CHAR(9) and "Waterloo" has only 8 chars.
I assume that this would return the expected results (LIKE and %). Or add the missing space.
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL LIKE ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "Waterloo%");
ResultSet rs = prepStmt.executeQuery();
The best way would by to use varchar instead of char if your Strings have a flexible length. Then the PreparedStatement would work as expected.
A workaround would be to use the Oracle specific setFixedCHAR method (but it's better to change the datatype to varchar if possible).
The following is from Oracle's PreparedStatement JavaDoc:
CHAR data in the database is padded to the column width. This leads to a limitation in using the setCHAR() method to bind character data into the WHERE clause of a SELECT statement--the character data in the WHERE clause must also be padded to the column width to produce a match in the SELECT statement. This is especially troublesome if you do not know the column width.
setFixedCHAR() remedies this. This method executes a non-padded comparison.
Notes:
Remember to cast your prepared statement object to OraclePreparedStatement to use the setFixedCHAR() method.
There is no need to use setFixedCHAR() for an INSERT statement. The database always automatically pads the data to the column width as it inserts it.
The following example demonstrates the difference between the setString(), setCHAR() and setFixedCHAR() methods.
// Schema is : create table my_table (col1 char(10));
// insert into my_table values ('JDBC');
PreparedStatement pstmt = conn.prepareStatement
("select count() from my_table where col1 = ?");
ResultSet rs;
pstmt.setString (1, "JDBC"); // Set the Bind Value
rs = pstmt.executeQuery(); // This does not match any row
// ... do something with rs
CHAR ch = new CHAR("JDBC ", null);
((OraclePreparedStatement)pstmt).setCHAR(1, ch); // Pad it to 10 bytes
rs = pstmt.executeQuery(); // This matches one row
// ... do something with rs
((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC");
rs = pstmt.executeQuery(); // This matches one row
// ... do something with rs

Categories

Resources