JDBC -- ResultSet values for column functions - java

How to get the outcome of the query-- the AVG(DIST).
MySQL is showing this result under the column "AVG(DIST)"-- no other clue.
How do i read this value from the ResultSet instance (rs in below code)?
PreparedStatement ps = c.prepareStatement("SELECT AVG(DIST) FROM POOL_TABLE");
ResultSet rs = ps.executeQuery();
ResultSet seems to be referring to them all by column names.
Not well-familiar to JDBC -- yet!
TIA.

You can use an alias name in the query and retrieve the value in any of the two ways.!
PreparedStatement ps = c.prepareStatement("SELECT AVG(DIST) AS AVERAGE_ALIAS FROM POOL_TABLE");
ResultSet rs = ps.executeQuery();
double avg = 0;
while (rs.next()) {
avg = rs.getDouble(1);
// OR
avg= rs.getDouble("AVERAGE_ALIAS");
}

Here it is:
double avg = 0;
while (rs.next()) {
avg = rs.getDouble(1);
}
Use alias if you have many aggregate functions in your query. See below answer!

PreparedStatement used for inserting of data,
i think you should use Statement.
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT AVG(DIST) FROM POOL_TABLE");
if( rs.next() ){
System.out.print( rs.getString(1) );
}
i hope this example would help you :)

Related

Java ResultSet Column count is always 1

I want to show the Column numbers of a table but it always shows the number 1. I have written the code below:
Class.forName(JDBC_DRIVER);
java.sql.Connection con=DriverManager.getConnection(DB_URL,USER,PASS);
try (Statement stmt = (Statement) con.createStatement()) {
String sql;
sql = "SELECT count(*) FROM information_schema.columns WHERE
table_name=\"my_b\"";
try (
ResultSet rs = stmt.executeQuery(sql)) {
int columCount = rs.getMetaData().getColumnCount();
System.out.println("Column number is: "+columCount);
}
stmt.close();
con.close();
Where is the error ?
First, you haven't needed Class.forName to load your JDBC drivers in a long time. Second, you are selecting a value but you are reading metadata. Third, when using try-with-resources you don't need explicit close calls (and your Connection should be closed in a finally, for example). Finally, use PreparedStatement and bind parameters. Like,
java.sql.Connection con = DriverManager.getConnection(DB_URL, USER, PASS);
String query = "SELECT count(*) FROM information_schema.columns WHERE table_name=?";
try (PreparedStatement stmt = con.prepareStatement(query)) {
stmt.setString(1, "my_b");
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
int columCount = rs.getInt(1);
System.out.println("Column number is: " + columCount);
} else {
System.out.println("No rows");
}
}
} finally {
con.close();
}
You are not retrieving the result of the query, instead you are asking the result set metadata how many columns the result set has. And as your query only produce a single column (ie COUNT(*)), the result of ResultSetMetaData.getColumnCount() is 1, and that value is correct.
If you want to get the result of the query, you need to get it from the result set:
try (ResultSet rs = stmt.executeQuery(sql)) {
if (rs.next()) {
int columnsNumber = rs.getInt(1);
System.out.println("Column number is: "+columnsNumber );
}
}
The problem is that ResultSet.getColumnCount returns the number of columns in the query's result set, not the number of columns in a table.
If you are trying to get a count of columns on a table, the query you have is correct. You just need to retrieve the result of the query, rather than its metadata.
String sql = "SELECT count(*) FROM information_schema.columns WHERE table_name=\"my_b\"";
try (
ResultSet rs = stmt.executeQuery(sql));
rs.next();
int columCount = rs.getInt(1);
System.out.println("Column number is: " + columCount);
}
Class.forName(JDBC_DRIVER);
java.sql.Connection con=DriverManager.getConnection(DB_URL,USER,PASS);
try (Statement stmt = (Statement) con.createStatement()) {
String sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = 'database_name' AND table_name = 'table_name'"
try (
ResultSet rs = stmt.executeQuery(sql)) {
//int columCount = rs.getMetaData().getColumnCount();
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
System.out.println("Column number is: "+columnsNumber );
}
stmt.close();
con.close();
Try SELECT * FROM information_schema.columns WHERE table_name=\"my_b\"
Just omit the count(*) since this returns a single result, while you are looking for all columns.

Return id after sql insert java [duplicate]

Is there a way to retrieve the auto generated key from a DB query when using a java query with prepared statements.
For example, I know AutoGeneratedKeys can work as follows.
stmt = conn.createStatement();
stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
However. What if I want to do an insert with a prepared Statement.
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql);
//this is an error
stmt.executeUpdate(Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
//this is an error since the above is an error
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
Is there a way to do this that I don't know about. It seems from the javadoc that PreparedStatements can't return the Auto Generated ID.
Yes. See here. Section 7.1.9. Change your code to:
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
stmt.executeUpdate();
if(returnLastInsertId) {
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
There's a couple of ways, and it seems different jdbc drivers handles things a bit different, or not at all in some cases(some will only give you autogenerated primary keys, not other columns) but the basic forms are
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
Or use this form:
String autogenColumns[] = {"column1","column2"};
stmt = conn.prepareStatement(sql, autogenColumns)
Yes, There is a way. I just found this hiding in the java doc.
They way is to pass the AutoGeneratedKeys id as follows
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
I'm one of those that surfed through a few threads looking for solution of this issue ... and finally get it to work. FOR THOSE USING jdbc:oracle:thin: with ojdbc6.jar PLEASE TAKE NOTE:
You can use either methods:
(Method 1)
Try{
String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
myPrepStatement = <Connection>.prepareStatement(yourSQL, Statement.RETURN_GENERATED_KEYS);
myPrepStatement.setInt(1, 123);
myPrepStatement.setInt(2, 123);
myPrepStatement.executeUpdate();
ResultSet rs = getGeneratedKeys;
if(rs.next()) {
java.sql.RowId rid=rs.getRowId(1);
//what you get is only a RowId ref, try make use of it anyway U could think of
System.out.println(rid);
}
} catch (SQLException e) {
//
}
(Method 2)
Try{
String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
//IMPORTANT: here's where other threads don tell U, you need to list ALL cols
//mentioned in your query in the array
myPrepStatement = <Connection>.prepareStatement(yourSQL, new String[]{"Id","Col2","Col3"});
myPrepStatement.setInt(1, 123);
myPrepStatement.setInt(2, 123);
myPrepStatement.executeUpdate();
ResultSet rs = getGeneratedKeys;
if(rs.next()) {
//In this exp, the autoKey val is in 1st col
int id=rs.getLong(1);
//now this's a real value of col Id
System.out.println(id);
}
} catch (SQLException e) {
//
}
Basically, try not used Method1 if you just want the value of SEQ.Nextval, b'cse it just return the RowID ref that you may cracked your head finding way to make use of it, which also don fit all data type you tried casting it to! This may works fine (return actual val) in MySQL, DB2 but not in Oracle.
AND, turn off your SQL Developer, Toad or any client which use the same login session to do INSERT when you're debugging. It MAY not affect you every time (debugging call) ... until you find your apps freeze without exception for some time. Yes ... halt without exception!
Connection connection=null;
int generatedkey=0;
PreparedStatement pstmt=connection.prepareStatement("Your insert query");
ResultSet rs=pstmt.getGeneratedKeys();
if (rs.next()) {
generatedkey=rs.getInt(1);
System.out.println("Auto Generated Primary Key " + generatedkey);
}

Get last inserted auto increment id in mysql

I am trying to get the mysql command like mysql_insert_id(); which retrieve the last inserted row's auto_increment id. What can I do to get it in Java?
rs = st.executeQuery("select last_insert_id() from schedule");
lastid = rs.getString("last_insert_id()");
my lastid was declared as INT. I dono what to use in rs.get and also the parameter..
Using JDBC, you can use Connection.PreparedStatement(query, int) method.
PreparedStatement pstmt = conn.prepareStatement(Query, Statement.RETURN_GENERATED_KEYS);
pstmt.executeUpdate();
ResultSet keys = pstmt.getGeneratedKeys();
keys.next();
key = keys.getInt(1);
Try using an alias
rs = st.executeQuery("select last_insert_id() as last_id from schedule");
lastid = rs.getString("last_id");
see this post for answer & explanation
Statement stmt = db.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
numero = stmt.executeUpdate();
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()){
risultato=rs.getInt(1);
}
Why not
SELECT MAX(id) FROM schedule
If id your column has a different name than id, you need to replace it accordingly in the above query.
You can use it like:
rs = st.executeQuery("SELECT MAX(id) AS id FROM schedule");
int lastid = rs.getInt("id");
You can use following query to get last auto_incremented ID of last inserted row.
SELECT (max(auto_incr_id)) from table_name;
Another option:
SELECT id FROM table_name ORDER BY id DESC LIMIT 1;
another way:
ResultSet rs = stmt.executeQuery("SELECT last_insert_id()");
while(rs.next()){
System.out.println("id = " + rs.getLong(1));
}

"ORA-01008: not all variables bound" error

I am using following method for calculating payroll by using jdbc but "ORA-01008: not all variables bound" error is not removing.
Any idea please?
I am using following code
public double getPayroll(){
ResultSet rs = null;
ResultSet rs1 = null;
ResultSet rs2 = null;
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getDBConnection();
double dailyPay=0,basicPay=0,payroll2=0;
int houseRent=0,convAllow=0,noOfPresents=0,empId=0;
String q = "select e_id from employee";
pstmt = conn.prepareStatement(q);
rs = pstmt.executeQuery();
while (rs.next()) {
empId=rs.getInt(1);
String q1 = "select count(att_status) from attendance where att_status='p'";
pstmt = conn.prepareStatement(q1);
rs1 = pstmt.executeQuery(q1);
while(rs1.next()){
noOfPresents=rs1.getInt(1);
String q2 = "select e_salary,e_house_rent,e_conv_allow from employee where e_id=?";
pstmt = conn.prepareStatement(q2);
pstmt.setInt(1,empId);
rs2 = pstmt.executeQuery(q2);
while(rs2.next()){
dailyPay=rs2.getInt(1)/22;
houseRent=rs2.getInt(2);
convAllow=rs2.getInt(3);
basicPay=dailyPay*noOfPresents;
payroll2+=basicPay+houseRent+convAllow;
}
}
}
return payroll2;
}catch (Exception e) {
e.printStackTrace();
return 0.0;
} finally {
try {
rs.close();
pstmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Your problem is here:
rs2 = pstmt.executeQuery(q2);
You're telling the PreparedStatement to execute the SQL q2, rather than executing the SQL previously prepared. This should just be:
rs2 = pstmt.executeQuery();
This is a fairly common mistake, caused mainly by the bad class design of java.sql.Statement and its subtypes.
As #RMT points out, you make the same mistake here:
rs1 = pstmt.executeQuery(q1);
This doesn't matter so much, since there are no placeholders in q1, so the SQL executes as-is. It's still wrong, though.
Lastly, you should consider calling close() on the first PreparedStatement, before re-assigning the pstmt variable to another one. You risk a leak if you don't do that.
pstmt = conn.prepareStatement(q2);
pstmt.setInt(1,empId);
rs2 = pstmt.executeQuery(q2);
You have already created the prepared statement with the query q2 and bound the variable empId to it. if you now invoke pstmt.executeQuery(q2), the variable binding is lost. The JDBC driver probably parses the unbound sql q2 when you execute pstmt.executeQuery(q2).
One reason might be that you cannot re-use the instance of pstmt like that. You have to use a separate PreparedStatement instance in each level of the loop.
Are you aware that this can be done with just a single statement as well?
Edit:
Assuming there is a relation between employee and attendance, something like this would return the sum in a single request:
select sum( (e_salary / 22) * att_count + e_house_rent + e_conv_allow )
from (
select emp.e_salary
emp.e_house_rent,
emp.e_conv_allow,
(select count(att.att_status) from attendance att where att.e_id = mp.e_id) s att_count
from employee emp
) t
If indeed attendance is not linked to employee, just leave out the where clause in the nested select.
UPDATE TESTCP SET CP_KEY2 =?, CP_DESC =?, CP_MAKER =?, CP_MAKER_DT =SYSDATE, CP_STATUS ='M' WHERE CP_LANGUAGE = ? AND CP_ENG_CODE = ? AND CP_KEY1 =? AND CP_LANGUAGE =?
In the above query we have 7 in parameter but if in your java code PreparedStatement you have set only 6 parameter values .
That time also this error will occur.

java : use of executeQuery(string) method not supported error?

I'm doing a simple preparedstatement query execution and its throwing me this error:
java.sql.SQLException: Use of the executeQuery(string) method is not supported on this type of statement at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.notSupported(JtdsPreparedStatement.java:197) at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:822) at testconn.itemcheck(testconn.java:58)
Any ideas what i'm doing incorrectly? thanks in advance
here is the code:
private static int itemcheck (String itemid ) {
String query;
int count = 0;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
con = java.sql.DriverManager.getConnection(getConnectionUrl2());
con.setAutoCommit(false);
query = "select count(*) as itemcount from timitem where itemid like ?";
//PreparedStatement pstmt = con.prepareStatement(query);
//pstmt.executeUpdate();
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1,itemid);
java.sql.ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
count = rs.getInt(1);
System.out.println(count);
} //end while
}catch(Exception e){ e.printStackTrace(); }
return (count);
} //end itemcheck
A couple of things are worth checking:
Use a different alias. Using COUNT as an alias would be asking for trouble.
The query object need not be passed twice, once during preparation of the statement and later during execution. Using it in con.prepareStatement(query); i.e. statement preparation, is enough.
ADDENDUM
It's doubtful that jTDS supports usage of the String arg method for PreparedStatement. The rationale is that PreparedStatement.executeQuery() appears to be implemented, whereas Statement.executeQuery(String) appears to have been overriden in PreparedStatement.executeQuery() to throw the stated exception.
So...
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1,itemid);
java.sql.ResultSet rs = pstmt.executeQuery(query);
Unlike Statement, with PreparedStatement you pass the query sql when you create it (via the Connection object). You're doing it, but then you're also passing it again, when you call executeQuery(query).
Use the no-arg overload of executeQuery() defined for PreparedStatement.
So...
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1,itemid);
java.sql.ResultSet rs = pstmt.executeQuery();

Categories

Resources