I want to execute the following query in java, through mysql jdbc: SELECT COUNT (*) FROM ORDERS, CUSTOMER WHERE O_ORDEYKEY = O_CUSTKEY
I have this code:
Connection conn = new DatabaseConnection().createMySQLConnection();
int totalRows=0;
for(int j=0;j<tables.size();j++)
{
Statement stmt = null;
ResultSet rs = null;
int rowCount = -1;
try {
conn.setAutoCommit(false);
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tables.get(j)
+ " WHERE O_ORDERKEY = O_CUSTKEY;");
rs.next();
rowCount = rs.getInt(1);
totalRows= totalRows+rowCount;
} finally {
rs.close();
stmt.close();
}
}
But I wanted to run it faster. How can I do this ?
For easier reading you should avoid the old implicit join syntax based on where and use the SQL standard (since 1992) explicit join syntax:
SELECT COUNT (*)
FROM ORDERS
INNER JOIN CUSTOMER ON ORDERS.O_ORDEYKEY = CUSTOMER.O_CUSTKEY
For better performance be sure you have an index on:
table ORDERS column O_ORDEYKEY
table CUSTOMER column O_CUSTKEY
Related
I needed to help shorten this code. My project contains this section 32x. So I want to ask if someone does not know how to simplify and generalize it.
conn[1] = DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD);
{
PreparedStatement stmt = conn[1].prepareStatement("SELECT * FROM nfl.minnesota");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
teamA = rs.getInt("MinnvsAt");
teamB = rs.getInt("AtvsMinn");
ID = rs.getBoolean("MinnvsAtP");
placement();
place();
}
PreparedStatement stmt1 = conn[1].prepareStatement("SELECT SUM(MinnvsAt) FROM nfl.minnesota WHERE MinnvsAtP = TRUE");
ResultSet rs1 = stmt1.executeQuery();
rs1.next();
int SUMPointsAH = rs1.getInt(1);
PreparedStatement stmt2 = conn[1].prepareStatement("SELECT SUM(MinnvsAt) FROM nfl.minnesota WHERE MinnvsAtP = FALSE");
ResultSet rs2 = stmt2.executeQuery();
rs2.next();
int SUMPointsAA = rs2.getInt(1);
PreparedStatement stmt3 = conn[1].prepareStatement("SELECT SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = TRUE");
ResultSet rs3 = stmt3.executeQuery();
rs3.next();
int SUMPointsBH = rs3.getInt(1);
PreparedStatement stmt4 = conn[1].prepareStatement("SELECT SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = FALSE");
ResultSet rs4 = stmt4.executeQuery();
rs4.next();
int SUMPointsBA = rs4.getInt(1);
pointsH.add(SUMPointsAA);
}
You could make your 4 queries, 2 queries with some parameters and extract two helper methods to be more DRY but overall to make your code more robust and readable because your declare too many variables that besides have a too broad scope.
You could write something like :
public int executeMinnvsAtPQuery(String MinnvsAtP){
String query = "SELECT SUM(MinnvsAt) FROM nfl.minnesota WHERE MinnvsAtP = ?";
PreparedStatement stmt = conn[1].prepareStatement(minnvsAtPQuery);
stmt.setString(1, MinnvsAtP);
ResultSet rs = stmt.executeQuery();
rs.next();
return rs.getInt(1);
}
public int executeAtvsMinnQuery(String AtvsMinn){
String query = "SELECT SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = ?";
PreparedStatement stmt = conn[1].prepareStatement(minnvsAtPQuery);
stmt.setString(1, AtvsMinn);
ResultSet rs = stmt.executeQuery();
rs.next();
return rs.getInt(1);
}
And use them in this way :
int SUMPointsAH = executeMinnvsAtPQuery("TRUE");
int SUMPointsAA = executeMinnvsAtPQuery("FALSE");
int SUMPointsBH = executeAtvsMinnQuery("TRUE");
int SUMPointsBA = executeAtvsMinnQuery("FALSE");
Note that the even if the two queries are very close, I don't think that you can make the sum(...) aggregate a parameter valuable by PreparedStatement.
And I would not recommend concatenation of SQL parts that is both error prone and not safe.
My project contains this section 32x.
To reduce this one to 1X, you could follow the same logic and extract the set of these queries in a method with some parameters that you may invoke anywhere then.
Note also that queries execution may have a cost in terms of execution time. So you should also ensure that your queries are optimized and required.
You can cut the actual number of queries executed in half by retrieving both columns at the same time.
You can supply TRUE or FALSE via a parameter.
So the only PreparedStatement you need is SELECT SUM(MinnvsAt), SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = ?.
So you can cut the whole thing in more than half.
As noted by #GriffeyDog, you can do the whole thing in one query, via GROUP BY:
SELECT SUM(MinnvsAt), SUM(AtvsMinn) FROM nfl.minnesota GROUP BY MinnvsAtP ORDER BY MinnvsAtP
So the first row will be the FALSE results and the second row will be the TRUE results, and the first column of each will be SUM(MinnvsAt) and the second SUM(AtvsMinn).
So only one PreparedStatement.executeQuery() needs to be executed.
I want to retrieve a particular column from the database. For a simple Select statement, I can able to able to retrieve a column like below
public String getDbColumnValue(String tableName, String columnName, String applicationNumber) {
String columnValue = null;
try {
PreparedStatement ps = null;
String query = "SELECT " + columnName + " FROM " + tableName +
" WHERE ApplicationNumber = ?;";
ps = conn.prepareStatement(query);
ps.setString(1, applicationNumber);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
columnValue = rs.getString(columnName);
return columnValue;
}
}
catch (Exception ex) {
}
return columnValue;
}
But, I'm using alias in my query like below. And this query works fine. How to use this in Java to retrieve a particular column
select S.StatusDesc from application A, StatusMaster S
where A.StatusMasterId = S.StatusMasterId and A.ApplicationNumber = '100041702404'
Any help would be greatly appreciated!
I think you are confusing simple aliases, which are used for table names, with the aliases used for column names. To solve your problem, you can just alias each column you want to select with a unique name, i.e. use this query:
select S.StatusDesc as sc
from application A
inner join StatusMaster S
on A.StatusMasterId = S.StatusMasterId and
A.ApplicationNumber = '100041702404'
Then use the following code and look for your aliased column sc in the result set.
PreparedStatement ps = null;
String query = "select S.StatusDesc as sc ";
query += "from application A ";
query += "inner join StatusMaster S ";
query += "on A.StatusMasterId = S.StatusMasterId ";
query += "and A.ApplicationNumber = ?";
ps = conn.prepareStatement(query);
ps.setString(1, applicationNumber);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
columnValue = rs.getString("sc");
return columnValue;
}
Note: I refactored your query to use an explicit inner join instead of joining using the where clause. This is usually considered the better way to write a query.
This question already has answers here:
ResultSet exception - before start of result set
(6 answers)
Closed 9 years ago.
I am getting the error Before start of result set I thought that I had to use next() on the ResultSet before retrieving data from the ResultSet ?
public void getPersonsOrders(String firstName){
Connection con = connect();
try{
Statement s = con.createStatement();
s.executeUpdate("use stl;");
ResultSet rs1 = s.executeQuery("select personID from person where first_name = " +"'"+firstName+"'"+";"); //get persons ID no.
ResultSet rs2 = s.executeQuery("select * from orderr where personID = "+rs1.getInt(1)+";"); //use ID no. to
rs2.next();
for(int i = 1; i < 4; i++){ //retrive order
System.out.println(rs2.getInt(i));
}
}
catch(SQLException e){
System.out.println("3" +e.getMessage());
}
}
You should execute
rs1.next();
before
ResultSet rs2 = s.executeQuery("select * from orderr where personID = "+rs1.getInt(1)+";");
Remember that you should close opened resources.
Regards.
You can use the following mechanism.
resultSet=s.executeQuery("select personID from person where first_name = " +"'"+firstName+"'"+";");
if (resultSet!= null)
{
do
{
//You can code your business logic here by getting data from db like:
System.out.println(resultSet.getString("first_name"));
} while (resultSet.next());
You don't call rs1.next() before reading from it with rs1.getInt(1).
As an aside, you can do this with a single SQL statement with a join are follows:
SELECT orderr.* FROM orderr JOIN person ON orderr.personID = person.personID WHERE person.first_name = ?
You should also use a java.sql.PreparedStatement like this:
PreparedStatement preparedStatement = connection.prepareStatement("SELECT orderr.* FROM orderr JOIN person ON orderr.personID = person.personID WHERE person.first_name = ?");
preparedStatement.setString(1, firstName);
ResultSet resultSet = preparedStatement.executeQuery();
The database will cache the query plan, which will help performance plus it will prevent SQL injection attacks.
Can anyone tell me how I can compare two resultset values? Only getting error in if statement, but the rest is working.
Statement s = con.createStatement();
Statement stmnt = con.createStatement();
String query = "select * from tbl_product";
s.execute(query);
ResultSet rs = s.getResultSet();
while(rs.next())
{
String strOuter=rs.getString(2);
System.out.println(strOuter);
String query1 = "select * from PRODUCTS_AJ";
stmnt.execute(query1);
ResultSet rs1 = stmnt.getResultSet();
while(rs1.next())
{
System.out.println("-------"+rs1.getString(2));
if(rs.getString(2).equals(rs1.getString(2)))// Getting Error here for this line
{
System.out.println("Found");
}
}
}
java.sql.Exception data not found
This types of error occurs when you try to read same column of the same cursor multiple times. And what you encountered is a typical scenario. Just store the string temporarily like bellow:
String col3 = rs1.getString(2);
and use col3 instead of rs1.getString(2), whenever needed.
System.out.println("-------"+ col3);
if(col3.equals(rs1.getString(2)))
{
...
You cannot re-read a column value again. So, copy it in a local variable for logging.
String val = rs1.getString(2);
System.out.println("-------" + val);
if (rs.getString(2).equals(val)) {
What you could possibly do is
use SQL where clause
String query1 = "select * from PRODUCTS_AJ where fieldNmae = 'something'";
ResultSetMetaData rsm = rs.getMetaData();
int colCount = rsm.getColumnCount();
if (colCount > 1)
{
// found
}
For ResultSetMetaData
or possibly do
ResultSet rsOLD = null;
ResultSet rs = s.getResultSet();
// rs will be new ResultSet
while(condition)
{
// check from second row (maintain if case)
.
.
.
// end of loop
rsOLD = rs;
}
Ok ! This is a typical error while using JDBC-ODBC bridge driver with MS Access. I have experienced.I solved it in following way. Retrieving the same data more than once from the result set.
Please try like this
ResultSet rs = s.getResultSet();
String str=rs.getString(2);
Use this string to compare
str.equals(rs2.getString(2)
Thanks!
rs.getSting(2) is executed the number of row times of rs1 in the while loop of rs1. You may not have the that many number of rows in rs as rs1.
How can i find out, from a Java program using JDBC if my table has a record with a specific primary key value? Can i use the ResultSet somehow after i issue a SELECT statement?
Count might be a better idea for this case. You can use it like so:
public static int countRows(Connection conn, String tableName) throws SQLException {
// select the number of rows in the table
Statement stmt = null;
ResultSet rs = null;
int rowCount = -1;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName + " WHERE.... ");
// get the number of rows from the result set
rs.next();
rowCount = rs.getInt(1);
} finally {
rs.close();
stmt.close();
}
return rowCount;
}
Taken from here.
You can do something like
private boolean hasRecord(String id) throws SQLException {
String sql = "Select 1 from MyTable where id = ?";
PreparedStatement ps = dbConn.prepareStatement(sql);
ps.setString(1,id);
ResultSet rs = ps.executeQuery();
return rs.next();
}
You can do that in four steps.
Write SQL. Something like select count(1) from table where column = 34343 will do.
Learn how to get connection using JDBC.
Learn about PreparedStatements in Java.
Learn how to read values from ResultSet.
select case
when exists (select 1
from table
where column_ = '<value>' and rownum=1)
then 'Y'
else 'N'
end as rec_exists
from dual;