java.sql.SQLException: Can not issue data manipulation statements with executeQuery() [duplicate] - java

This question already has answers here:
Cannot issue data manipulation statements with executeQuery()
(11 answers)
Closed 6 years ago.
I can't seem to work out the bug. I need the ResultSet though to get the actual Object. The error is: java.sql.SQLException: Can not issue data manipulation statements with executeQuery(). at rs = pst.executeQuery();. Code:
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
String url = null; //Set, but not visible in code.
String user = null; //Set, but not visible in code.
String password = null; //Set, but not visible in code.
public Object get(String table, String key){
try {
con = DriverManager.getConnection(url, user, password);
String query = "SELECT * FROM `" + table + "` WHERE key = ?;";
pst = con.prepareStatement(query);
pst.setString(1, key);
pst.executeUpdate();
rs = pst.executeQuery();
rs.next();
return rs.getObject(1);
} catch (SQLException ex) {
return null;
} finally {
try {
if (rs != null) {
rs.close();
}
if (pst != null) {
pst.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
return null;
}
}
}

donot use executeQuery use executeUpdate that your sql statement is
between (update,insert,delete) see
https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeUpdate(java.lang.String)

Related

How to fix "Declaration, final or effectively final variable expected" in a PreparedStatement.setString

The problem is that I am trying to set a wild card in a PreparedStatement but the setString statement is giving me the error above.
I have tried changing it to a setObeject statement with multiple different types like Types.VARCHAR. I have tried declaring the PreparedStatement in different places, and I have tried declaring 'name' in the method and in the class.
public String getTemplateText(String name) {
try (
Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT templateText FROM TEMPLATE WHERE " +
"templateTag = ?");
stmt.setString(1 , name); // this is the line that has the problem!
ResultSet rs = stmt.executeQuery()
) {
System.out.println("Set Text...");
String tempText = rs.getString("templateText");
return tempText;
} catch (SQLException e) {
e.printStackTrace();
}
return "";
}
/* this is the SQL code for the table that I am trying to query */
CREATE TABLE TEMPLATE
(
templateID INTEGER PRIMARY KEY IDENTITY(1,1)
, templateText TEXT
, templateTag CHAR(25)
);
You can't set the stmt parameter in your try-with-resources (because binding the parameter is void and not closable). Instead, you can nest a second try-with-resources after you bind the parameter. Like,
public String getTemplateText(String name) {
try (Connection conn = getConnection();
PreparedStatement stmt = conn
.prepareStatement("SELECT templateText FROM TEMPLATE WHERE " +
"templateTag = ?")) {
stmt.setString(1, name);
try (ResultSet rs = stmt.executeQuery()) {
System.out.println("Set Text...");
String tempText = rs.getString("templateText");
return tempText;
}
} catch (SQLException e) {
e.printStackTrace();
}
return "";
}

Using ResultSet to return string value from database but method skips the "Try" clause?

Why is my following code:
PrintWriter pw = response.getWriter();
pw.println(getValueOf(SQL, "lastName");
not printing anything after passing it into my method:
public static String getValueOf(String sql, String colName)
{
String result = "";
try
{
Connection conn = (Connection) accessDB.connecttoDB(); // pre-defined funct in my other class that works
PreparedStatement pst = (PreparedStatement) conn.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while (rs.next())
result = rs.getString(colName);
conn.close();
return result;
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}
In other words, why does it seem to be skipping the "try" clause entirely and just jumping to return the empty "" result at the end?
My SQL statment:
String SQL = "SELECT lastName FROM customers WHERE firstName=\"Bob\";";
I do have an entry for the person "Bob" (his lastname is "Mike") in my Customers table.
My Customers Table:
lastName / firstName / address / email
EDIT
It works correctly if I change the return type to "void" but I actually need a String value.
Alternate code:
public static void getValueOf(String sql, String colName, PrintWriter pw)
{
try
{
Connection conn = (Connection) accessDB.connecttoDB(); // pre-defined funct in my other class that works
PreparedStatement pst = (PreparedStatement) conn.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while (rs.next())
pw.println(rs.getString(colName)); // This does print out to the webpage as "Mike"
conn.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
Based upon your last edit, I would guess that you have more than one records.
So change your code to
if (rs.next()) {
result = rs.getString(colName);
}
And also, your code does not skip that try block

How to solve ORA-0300: maximum open cursors exceeded exception [duplicate]

This question already has answers here:
java.sql.SQLException: - ORA-01000: maximum open cursors exceeded
(14 answers)
Closed 5 years ago.
I have got ORA-0300: maximum open cursors exceeded exception
public void connectionexample(String email)
{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = db.getConnection();
ps = conn.prepareStatement(select_query);
ps.setString(1, email);
rs = ps.executeQuery();
if(rs.next()) {
ps = conn.prepareStatement(update_query);
ps.setString(1, email);
ps.executeUpdate();
} else {
ps = conn.prepareStatement(insert_query);
ps.setString(1, email);
ps.executeUpdate();
}
} catch(Exception e) {
LOG.error("Exception occured ", e);
} finally {
DATABASE.release(rs);
DATABASE.release(ps);
DATABASE.release(conn);
}
}
You get this error because you are using the same PrepapredStatement multiple time :
ps = conn.prepareStatement(select_query);//<<----------------------Here
...
if (rs.next()) {
ps = conn.prepareStatement(update_query);//<<-------------------Then here
...
} else {
ps = conn.prepareStatement(insert_query);//<<-------------------or here
...
}
To solve your problem you have to close your statement and create a new one for the new query, or for better way, separate the actions in a different methods which each one create and release its statement and connection.
You are re-using the prepared statement ps:
public void connectionexample(String email)
{
Connection conn = null;
PreparedStatement ps = null;
PreparedStatement ps2 = null; -- Use another variable for the second prepared statement
ResultSet rs = null;
try {
conn = db.getConnection();
ps = conn.prepareStatement(select_query);
ps.setString(1, email);
rs = ps.executeQuery();
if(rs.next()) {
ps2 = conn.prepareStatement(update_query); -- Assign this to the second variable
} else {
ps2 = conn.prepareStatement(insert_query);
}
ps2.setString(1, email);
ps2.executeUpdate();
} catch(Exception e) {
LOG.error("Exception occured ", e);
} finally {
DATABASE.release(rs);
DATABASE.release(ps);
DATABASE.release(ps2); -- Make sure you also close the second prepared statement
DATABASE.release(conn);
}
}
However, you could get rid of the second round-trip to the database by using the SQL MERGE statement.

ResultSet not open although i have only one at a time

I know many questions were asked before for this issue but for this situations I can't find an answer.
This is my code:
private Collection<Coupon> getCouponsMain(Company company, String filters) throws DAOException
{
String sql = null;
if (filters != null)
{
sql = "SELECT couponsystem.coupon.* FROM couponsystem.company_coupon LEFT JOIN couponsystem.coupon ON "
+ "couponsystem.company_coupon.COUPON_ID = couponsystem.coupon.ID WHERE couponsystem.company_coupon.COMP_ID = ? AND ?";
}
else
{
sql = "SELECT couponsystem.coupon.* FROM couponsystem.company_coupon LEFT JOIN couponsystem.coupon ON "
+ "couponsystem.company_coupon.COUPON_ID = couponsystem.coupon.ID WHERE couponsystem.company_coupon.COMP_ID = ?";
}
try (Connection con = pool.OpenConnection(); PreparedStatement preparedStatement = con.prepareStatement(sql);)
{
// query command
preparedStatement.setLong(1, company.getId());
if (filters != null)
{
preparedStatement.setString(2, filters);
}
ResultSet rs = preparedStatement.executeQuery();
if (rs.next())
{
CouponDBDAO couponDao = new CouponDBDAO();
rs.previous();
return couponDao.BuildCoupons(rs);
}
else
{
return null;
}
}
catch (SQLException | NullPointerException e)
{
throw new DAOException("Failed to retrieve data for all coupons" + e.getMessage());
}
}
I think the query itself is not the important issue here but, once I use next() for the ResultSet, I get the error:
java.sql.SQLException: Operation not allowed after ResultSet closed"
This usually happened when using two rs for same statement, this is not the case this time.
Due to many issues with previous method and BuildCoupons(rs) issue, also this part does not work properly for the same reason:
#Override
public Company getCompany(long id) throws DAOException
{
String sql = "SELECT * FROM couponsystem.company WHERE ID = ?";
try (Connection con = pool.OpenConnection(); PreparedStatement preparedStatement = con.prepareStatement(sql);)
{
// query command
preparedStatement.setLong(1, id);
// query execution
ResultSet rs = preparedStatement.executeQuery();
Company comp = new Company();
if (rs.next())
{
//Fill customer object from Customer table
comp.setId(rs.getLong("ID"));
comp.setCompName(rs.getString("COMP_NAME"));
comp.setPassword(rs.getString("PASSWORD"));
comp.setEmail(rs.getString("EMAIL"));
comp.setCoupons(comp.getCoupons());
}
else
{
comp = null;
}
return comp;
}
catch (SQLException e)
{
throw new DAOException("Failed to retrieve data for customer id: " + id);
}
}
BTW - working with MySQL and insert, update and delete queries are working properly so there not issue with the connection to the db
Another update -
Once i replace it to regular statement, it's working but of course i'm losing all the advantages of prepared statement
Like i said i create new code in order to isolate the big program
This is the code:
public class testState
{
public static void main(String[] args) throws SQLException
{
DBDAO pool = DBDAO.getInstance();
String sql = "SELECT ID FROM couponsystem.company WHERE COMP_NAME = ? AND PASSWORD = ?";
String compName = "t";
String password = "t";
pool.CreatePool();
Connection con = pool.OpenConnection();
PreparedStatement preparedStatement = con.prepareStatement(sql);
preparedStatement.setString(1, compName);
preparedStatement.setString(2, password);
preparedStatement.executeQuery();
ResultSet rs = preparedStatement.executeQuery();
System.out.println("rs status: " + rs.isClosed());
if (rs.next())
{
System.out.println("log-in was successfuly performed");
System.out.println(rs.getLong(1));
System.out.println("hjhjh");
}
else
{
System.out.println("-1");
}
rs.close();
preparedStatement.close();
con.close();
pool.CloseConnection();
}
}
Problem was solved,
this is the problem:
sql = "SELECT couponsystem.coupon.* FROM couponsystem.company_coupon LEFT JOIN couponsystem.coupon ON "
+ "couponsystem.company_coupon.COUPON_ID = couponsystem.coupon.ID WHERE couponsystem.company_coupon.COMP_ID = ? AND ?";
the second ? is illegal, but the exception is ResultSet closed and not query issue
the problem is you are trying to go back to the previous record in the result set which is not possible.
learn about scrollable resultset and make it insensitive, once you use this you can go back to the previous record by using rs.previous()
ResultSet.TYPE_SCROLL_INSENSITIVE

Assign to string instead of resultset for jdbc query

I need to get the output of a jdbc query, but wherever I google, it returns a resultset. But, its just a single row. Here is my query
ResultSet rsLocationId = null;
rsLocationId = stmtLocation.executeQuery("SELECT apmcid FROM userbusinesstoapmc WHERE userbusinessid='"+userBusinessKey+"'");
It should return a single record as a string. How can I convert it? Any ideas would be greatly appreciated.
I suggest you use PreparedStatement and bind the parameter, currently you are vulnerable to SQL Injection attacks.
PreparedStatement ps = null;
ResultSet rs = null;
String result = null;
final String sql = "SELECT apmcid FROM userbusinesstoapmc "
+ "WHERE userbusinessid=?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1, userBusinessKey);
rs = ps.executeQuery();
if (rs.next()) {
result = rs.getString("apmcid");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
you can try like this
ResultSet rsLocationId = null;String result="";
rsLocationId = stmtLocation.executeQuery("SELECT apmcid FROM userbusinesstoapmc WHERE userbusinessid='"+userBusinessKey+"'");
if(rsLocationId.next())
{
result=rsLocationId.getString('apmcid');
}
Even though your particular query only returns a single column, presumably some CHAR type if you expect the result to be a String, the executeQuery method returns a result set object, not a String object. So, you have to process the result set to get your String data. SpringLearner has provided a good example of how to do this.

Categories

Resources