Spring MVC - After end of result set (SQL) - java

I'm trying to send in ORDER table last ID from CUSTOMER and all IDs from PRODUCT tables. In "idproduct"(ORDER table) should appears all IDs with white spaces between them. I used here rs.next() twice and I know that it isthe reason why error appears, but how can I handle it? Here is a code:
List<String> IDproducts = new ArrayList<>();
Connection conn = db.getConnect();
PreparedStatement pst = conn.prepareStatement("SELECT * FROM `onlineshop`.`customer`");
ResultSet rs = pst.executeQuery();
while (rs.next()){
rs.getString(1);
}
Connection conn1 = db.getConnect();
PreparedStatement pst1 = conn1.prepareStatement("SELECT * FROM `onlineshop`.`product`");
ResultSet rs1 = pst1.executeQuery();
while (rs1.next()){
IDproducts.add(rs1.getString(1));
}
db.Query("INSERT INTO `onlineshop`.`order` (`idcustomer`, `idproduct`)
VALUES ('"+rs.getString(1)+"','" + IDproducts + ")");
error:
java.sql.SQLException: After end of result set
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:959)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:862)
com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:790)
com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5244)
com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5167)

Related

Basic JDBC select working, when I switch to prepared statement it doesn't work

I am using Java 8 and oracle.
I have confirmed that this code is working:
Statement stmt = null;
String query = "select * from custref";
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String cName = rs.getString("CUSTOMER_NAME");
System.out.println(cName);
}
When I change it to this, it does not give any results:
PreparedStatement prepStmt = null;
String query = "select * from custref where CUSTOMER_NUMBER = ?";
prepStmt = con.prepareStatement(query);
prepStmt.setString(1, "12344321");
ResultSet rs = prepStmt.executeQuery();
while (rs.next()) {
String cName = rs.getString("CUSTOMER_NAME");
System.out.println(cName);
}
I have confirmed that my data type is VARCHAR hence the set string. I know my connections are fine because the basic search works just when I switch to parameterized it doesn't fail or throw exceptions it just doesn't have a result set. I have also tried the :customerNumber convention instead of the ? and this didn't work either. This is quite embarrassing but I am at my end here, nothing I can find seems to address this.

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.

Count entris from table in H2 Database Engine

I know that I can count the entries in SQL with
SELECT COUNT (*) FROM table
but I don't know how do perfom that in Java.
This is my Code to perform a SQL command.
Statement stmt = conn.createStatement();
stmt.executeQuery("SELECT COUNT (*) FROM table")
Result:
rs2: org.h2.result.LocalResult#41cf3f60 columns: 1 rows: 1 pos: -1
But it should return > 20
My code:
Connection conn = null;
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection(
"jdbc:h2:" + Environment.getExternalStorageDirectory()
+ "/sorter/database", "", "");
Statement stmt = conn.createStatement();
Toast.makeText(context,
String.valueOf(stmt.executeQuery(sql)),
Toast.LENGTH_LONG).show();
conn.close();
if (conn != null)
conn.close();
What you see is the toString() method of the ResultSet you never actually retrieve a value from the result.
executeQuery returns a ResultSet that you use to get the actual data. It is not the result of the query directly (think about how this should work when returning multiple rows and multiple columns)
You need to do something like this:
ResultSet rs = stmt.executeQuery(sql);
int count = -1;
if (rs.next())
{
count = rs.getInt(1);
}
This is all nicely explained in the JDBC Tutorial:
http://docs.oracle.com/javase/6/docs/technotes/guides/jdbc/getstart/resultset.html#998035
Another possibility is
ResultSet rs=conn.prepareStatement("SELECT COUNT(*) FROM table").executeQuery();
if(rs.next()) sysout(rs.getInt(1));

Dynamic Delete query

Im trying to make a dynamic Delete Query.
What im basically trying to do is first grab the name of the first column in any table (the primary key). Then i use that in Another Query to delete from that table though i get a nullpointerexception?
Ohh and the primary key is not an INT like 1,2,3,4,5 etc.. it's formed up as S1,S2,S3,S4,S5 etc and has the type TEXT.
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:test.db");
c.setAutoCommit(true);
System.out.println("Opened database successfully");
ResultSet rs = stmt.executeQuery("SELECT * FROM "+tablename);
ResultSetMetaData rsmd = rs.getMetaData();
FirstColumn = rsmd.getColumnName(1);
String query = "DELETE FROM "+tablename+" WHERE " +FirstColumn+ " = " +row;
stmt = c.createStatement();
stmt.executeUpdate(query);
stmt.close();
c.close();
I am going to assume that all the variables you are using have been initialized.
I added single quotes around the FirstColumn name.
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:test.db");
c.setAutoCommit(true);
System.out.println("Opened database successfully");
ResultSet rs = stmt.executeQuery("SELECT * FROM "+tablename);
ResultSetMetaData rsmd = rs.getMetaData();
FirstColumn = rsmd.getColumnName(1);
String query = "DELETE FROM "+ tablename +" WHERE " + FirstColumn + " = '" + row + "'";
stmt = c.createStatement();
stmt.executeUpdate(query);
stmt.close();
c.close();
If you are still getting an error you should try printing out your row name and see what it prints out.
Edit: Since you are new stylistically it's preferable to add a single space when using operators to improve code readability. For example 1+3+x+34 is a lot harder to read than 1 + 3 + x + 34. Granted there is no "wrong" code style but improving code readability is always a plus.
Initialize your stmt object...
stmt = c.createStatement();
before executing the query.

RowSet is not write enabled

Please help me out, I am trying to update the value of one column in a rowset but I am continously getting an exception..that rowset is not write enabled.
I searched a lot but didn't find a way to make the rowset write enabled.
Mentioning below the code that I am using and the following exception:
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:orcl", uname, pwd);
String query = "select * from " + table;
PreparedStatement preparedStatement = conn.prepareStatement(query);
ResultSet rset = preparedStatement.executeQuery();
OracleCachedRowSet oracleCachedRowSet = new OracleCachedRowSet();
oracleCachedRowSet.populate(rset);
ResultSetMetaData resultSetMetaData = oracleCachedRowSet.getMetaData();
int numberOfColumns = resultSetMetaData.getColumnCount();
while (oracleCachedRowSet.next()) {
oracleCachedRowSet.updateBigDecimal(1, new BigDecimal(99));
oracleCachedRowSet.updateRow();
oracleCachedRowSet.acceptChanges();
for (int i = 1; i <= numberOfColumns; i++) {
System.out.print(oracleCachedRowSet.getString(i) + " ");
}
}
}
Exception coming on executing the above code :
java.sql.SQLException: The RowSet is not write enabled
at oracle.jdbc.rowset.OracleCachedRowSet.checkColumnIndex(OracleCachedRowSet.java:912)
at oracle.jdbc.rowset.OracleCachedRowSet.updateObject(OracleCachedRowSet.java:5931)
at oracle.jdbc.rowset.OracleCachedRowSet.updateBigDecimal(OracleCachedRowSet.java:6430)
at Test.getDBConnection(Test.java:86)
at Test.main(Test.java:37)
Try setting:
oracleCachedRowSet.setReadOnly(false);
Javadoc for ResultSet tells us
A default ResultSet object is not updatable and has a cursor that moves forward only.
I guess, the message of your exception is related to that issue. The javaDoc provides an example how to create a scrollable and updateable result set:
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
// rs will be scrollable, will not show changes made by others,
// and will be updatable

Categories

Resources