I tried to get specific value where the column of names in my database contains "jansen",but when i run my code it shows error like this
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'jansen' in 'where clause'
here is my code
try {
Statement stmt=MyConnection.getConnection().createStatement();
ResultSet rs=stmt.executeQuery("select * from emp where name = jansen");
while(rs.next())
System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getString(3));
}catch (Exception e){
System.out.println(e);
}
[and here is my database in Sqlyog]
You should put quotes around string values in your SQL statement.
"select * from emp where name = 'jansen'"
Another issue you may run into later, is that your resources (e.g. connection, statement, ...) aren't cleaned up after you've used them. You should actually call the close() function after using it. You would then have to put that code inside a finally block, and again catch it to prevent having the close function itself throwing exceptions. Because it would be messy and bloated, there's a better solution to clean things up:
Create your statement between the braces of your try, and it will close it cleanly for you. (It's called a try-with-resources statement)
try (Statement stmt = MyConnection.getConnection().createStatement()) {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
...
}
} catch (SQLException e) {
System.out.println(e);
}
You can read more about executing SQL statements in java, in the official tutorial.
You should use a PreparedStatement instead of Statement in this way:
PreparedStatement statement = MyConnection.getConnection().prepareStatement("select * from emp where name = :empId");
statement.setString(empId, "jansen");
ResultSet rs = statement.executeQuery();
Then "jansen" would be replaced by String variable with dynamic name.
Related
This question already has answers here:
Java MYSQL Prepared Statement Error: Check syntax to use near '?' at line 1
(2 answers)
Closed 1 year ago.
I faced this problem today with my select SQL. This method is supposed to show data from database in tex tfields. I changed it from statement to preparedStatement, but I faced a problem.
public Entreprise loadDataModify(String id) {
Entreprise e = new Entreprise();
PreparedStatement stmt;
try {
String sql = "SELECT * FROM user WHERE mail=?";
stmt = cnx.prepareStatement(sql);
stmt.setString(1, id);
ResultSet rst = stmt.executeQuery(sql);
while (rst.next()) {
stmt.setString(2, e.getNom());
stmt.setString(3, e.getEmail());
stmt.setString(4, e.getTel());
stmt.setString(5, e.getOffre());
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
return e;
}
It shows i have problem with syntax and the output is " nu
You're calling the wrong method. Unlike Statement, when you're using a PreperedStatement you should first set the values for the parameters, and after you can call on that instance executeQuery() method.
Also, it's a best practice to use try-with-resources, because a Statement or PreparedStament object is a Resource (a resource is a class that implements AutoCloseable interface) and you have to close it. Using try-with-resources, it's done automatically.
The ResultSet instance is also a resource, but it's closed when the statement object is closed, so you don't have to close it explicitly.
So, the best way to solve your problem will be:
String selectAllByMail = "SELECT * FROM user WHERE mail=?";
try (PreparedStatement prpStatement = connection.prepareStatement(selectAllByMail)) {
// use prpStatement
prpStatement.setString(1, id);
ResultSet resultSet = prpStatement.executeQuery();
while (resultSet.next()) {
// process resultSet
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
You are not filling your Enterprise object. And you are not using executeQuery() function correctly. As seen below, the parameter inside the brackets has been removed. PreparedStatements first of all need the values of the parameters (your ? in the query) and then the formed query has to be executed. If you give a String parameter to executeQuery() then the query in the brackets will be executed.
And the part where Enterprise is being filled could be seen below.
This would be the correct way:
public Entreprise loadDataModify(String id) {
Entreprise e = new Entreprise();
PreparedStatement stmt;
try {
String sql = "SELECT * FROM user WHERE mail=?";
stmt = cnx.prepareStatement(sql);
stmt.setString(1, id);
ResultSet rst = stmt.executeQuery();
while (rst.next())
{
// rst keeps the data, so you have to traverse it and get the data from it in this way.
e.setNom( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
e.setEmail( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
e.setTel( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
e.setOffre( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
return e;
}
Your call to executeQuery() should not be passing the query string. Use this version:
String sql = "SELECT * FROM user WHERE mail=?";
stmt = cnx.prepareStatement(sql);
stmt.setString(1, id);
ResultSet rst = stmt.executeQuery();
while (rst.next()) {
// process result set
}
Your current code is actually calling some overloaded Statement#executeQuery() method, which is not the version of the method which you want to be calling.
If I create a statement with JDBC and execute a query, do I need to close said statement and create a new one before executing again? Eclipse doesn't complain about the second case.
try {
connection = dataSource.getConnection();
try {
statement = connection.createStatement();
statement.execute("set search_path to '...'");
} finally {
Utils.tryClose(statement);
}
try {
statement = connection.createStatement();
statement.execute("SET statement_timeout TO " + (QUERY_TIMEOUT_SECONDS * 1000));
} finally {
Utils.tryClose(statement);
}
try {
statement = connection.createStatement();
statement.execute(query);
} finally {
Utils.tryClose(statement);
}
} finally {
Utils.tryClose(connection);
}
As opposed to:
try {
connection = dataSource.getConnection();
statement = connection.createStatement();
statement.execute("set search_path to '...'");
statement.execute("SET statement_timeout TO " + (QUERY_TIMEOUT_SECONDS * 1000));
statement.execute(query);
} finally {
Utils.tryClose(statement);
Utils.tryClose(connection);
}
That is not required you can use the same statement to query the DB multiple times, the only thing to remember is that each resultset returned with a statement execution will be closed after creating a new statemnet. Quoting from java docs:-
By default, only one ResultSet object per Statement object can be open at the same time. Therefore, if the reading of one ResultSet object is interleaved with the reading of another, each must have been generated by different Statement objects. All execution methods in the Statement interface implicitly close a statment's current ResultSet object if an open one exists.
Hence you can do something like this:-
try {
connection = dataSource.getConnection();
statement = connection.createStatement();
ResultSet rs1=statement.execute("....");
//parse rs1
//close rs1
ResultSet rs2= statement.execute(....);
//parse rs1
//close rs1
} finally {
Utils.tryClose(statement);
Utils.tryClose(connection);
}
I am not sure why eclipse is complaining in case of PreparedStatements, the whole purpose of PreparedStatements is to define a query structure and execute the query multiple times by only changing the parameters. For example when you want to parse and insert a large text file into DB. Quoting from javadocs
If you want to execute a Statement object many times, it usually reduces execution time to use a PreparedStatement object instead.
i have the following exception:
here is the relevant code parts:
Server.Proxy.update_allLogOut: (line 65 is the while bracket)
public void update_allLogOut ()
{
try
{
ResultSet rs;
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM sysuser WHERE login=1");
while(rs.next())
{
stmt.executeUpdate("UPDATE sysuser SET login=0");
}
rs.close();
} catch (SQLException e) {e.printStackTrace();}
}
Server.Server.:
public Server(int port)
{
super(port);
func.update_allLogOut();
}
main:
Server sv = new Server(5555);
i must point out that 99% of times it runs with no exceptions.. but several times i get this exception that i cant figure out why it happens. any ideas? it is clear that something is done wrong yet all similar topics here have not given the answer in this case...
You are using stmt to both iterate over the results of SELECT and to UPDATE inside the loop. This doesn't work since the moment you execute the UPDATE, the result set associated with the SELECT gets closed.
To fix, use two separate Statement objects.
I'm not sure, that this block:
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM sysuser WHERE login=1");
while(rs.next())
{
stmt.executeUpdate("UPDATE sysuser SET login=0");
}
rs.close();
is a good idea.
Why not just execute simple query: UPDATE sysuser SET login=0 WHERE login=1?
Furthermore, using same stmt inside while loop - it is rough mistake.
I'm new to java but I'm picking it up pretty quickly. One thing that I keep running into is I end up having one function that is full of queries and just code in general and I would like to break it down into separate functions. Take this for example:
public ResultSet getApples (){
ResultSet rs;
try{
PreparedStatement stmt = con.prepareStatement("SELECT * FROM fruit WHERE type='apples'");
rs = stmt.executeQuery();
} catch (SQLException e){
e.printStackTrace();
}
return rs;
}
Ideally this would be what I want to do, have all of try's and catches within one function, but this gives me the error: Local variable may not have been initilized
I do realize I could do this:
public function start(){
try{
ResultSet apples = getApples();
catch (SQLException e){
e.printStackTrace();
}
}
public ResultSet getApples () throws SQLException {
PreparedStatement stmt = con.prepareStatement("SELECT * FROM fruit WHERE type='apples'");
return stmt.executeQuery();
}
But I would really rather have the exceptions handled within the function as well as it return a result.
EDIT
Alright so kinda a modififed answer to whats being provided. My whole goal on this question was to make the main functions of my script as clean as possible. Even the extra if ( _resultSet != null ) was something that I didn't really like. That being said I am pretty happy with this result:
public ResultSet getApples (){
try{
PreparedStatement stmt = con.prepareStatement("SELECT * FROM fruit WHERE type='apples'");
return stmt.executeQuery();
} catch (SQLException e){
System.out.println("************************");
System.out.println("Class.getApples null");
System.out.println(e.getMessage());
return null;
}
}
Everything is handled within the getApples function and when _resultSet.next() is called I get a NullPointerException and the prints in the getApples exception so I am able to find the error and debug quickly.
Initialize rs to null first.
public ResultSet getApples (){
ResultSet rs = null;
try{
PreparedStatement stmt = con.prepareStatement("SELECT * FROM fruit WHERE type='apples'");
rs = stmt.executeQuery();
} catch (SQLException e){
e.printStackTrace();
}
return rs;
}
You can declare your RS like this
ResultSet rs = null;
but where you call your function:
ResultSet apples = getApples ()
you have to check:
if(apples == null)
{
//do something, because your query did not work.
}
Because you are not setting ResultSet rs to anything initial value. and at the end you are returning it.
What if any exception occurs and rs value does not have value set in it. In order to solve you need to assign null value to rs when you declare.
The biggest problem that I see with your first example (other than not initializing rs) is that you don't properly handle cleanup. You should have a finally block that closes stmt.
One very good way to make sure that all of this happens is to use Spring's JDBCTemplate (more documentation here). This handles all of the connection management details for you; you simply write your SQL and code to process the ResultSet. Better, it lets you use Spring's declarative transaction management.
You can use CachedRowSet. For detailed answer you can look at my answer here
As soon as my code gets to my while(rs.next()) loop it produces the ResultSet is closed exception. What causes this exception and how can I correct for it?
EDIT: I notice in my code that I am nesting while(rs.next()) loop with another (rs2.next()), both result sets coming from the same DB, is this an issue?
Sounds like you executed another statement in the same connection before traversing the result set from the first statement. If you're nesting the processing of two result sets from the same database, you're doing something wrong. The combination of those sets should be done on the database side.
This could be caused by a number of reasons, including the driver you are using.
a) Some drivers do not allow nested statements. Depending if your driver supports JDBC 3.0 you should check the third parameter when creating the Statement object. For instance, I had the same problem with the JayBird driver to Firebird, but the code worked fine with the postgres driver. Then I added the third parameter to the createStatement method call and set it to ResultSet.HOLD_CURSORS_OVER_COMMIT, and the code started working fine for Firebird too.
static void testNestedRS() throws SQLException {
Connection con =null;
try {
// GET A CONNECTION
con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
String sql1 = "select * from reportes_clasificacion";
Statement st1 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs1 = null;
try {
// EXECUTE THE FIRST QRY
rs1 = st1.executeQuery(sql1);
while (rs1.next()) {
// THIS LINE WILL BE PRINTED JUST ONCE ON
// SOME DRIVERS UNLESS YOU CREATE THE STATEMENT
// WITH 3 PARAMETERS USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
System.out.println("ST1 Row #: " + rs1.getRow());
String sql2 = "select * from reportes";
Statement st2 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// EXECUTE THE SECOND QRY. THIS CLOSES THE FIRST
// ResultSet ON SOME DRIVERS WITHOUT USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
st2.executeQuery(sql2);
st2.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
rs1.close();
st1.close();
}
} catch (SQLException e) {
} finally {
con.close();
}
}
b) There could be a bug in your code. Remember that you cannot reuse the Statement object, once you re-execute a query on the same statement object, all the opened resultsets associated with the statement are closed. Make sure you are not closing the statement.
Also, you can only have one result set open from each statement. So if you are iterating through two result sets at the same time, make sure they are executed on different statements. Opening a second result set on one statement will implicitly close the first.
http://java.sun.com/javase/6/docs/api/java/sql/Statement.html
The exception states that your result is closed. You should examine your code and look for all location where you issue a ResultSet.close() call. Also look for Statement.close() and Connection.close(). For sure, one of them gets called before rs.next() is called.
You may have closed either the Connection or Statement that made the ResultSet, which would lead to the ResultSet being closed as well.
Proper jdbc call should look something like:
try {
Connection conn;
Statement stmt;
ResultSet rs;
try {
conn = DriverManager.getConnection(myUrl,"","");
stmt = conn.createStatement();
rs = stmt.executeQuery(myQuery);
while ( rs.next() ) {
// process results
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
} finally {
// you should release your resources here
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
you can close connection (or statement) only after you get result from result set. Safest way is to do it in finally block. However close() could also throe SqlException, hence the other try-catch block.
I got same error everything was correct only i was using same statement interface object to execute and update the database.
After separating i.e. using different objects of statement interface for updating and executing query i resolved this error. i.e. do get rid from this do not use same statement object for both updating and executing the query.
Check whether you have declared the method where this code is executing as static. If it is static there may be some other thread resetting the ResultSet.
make sure you have closed all your statments and resultsets before running rs.next. Finaly guarantees this
public boolean flowExists( Integer idStatusPrevious, Integer idStatus, Connection connection ) {
LogUtil.logRequestMethod();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement( Constants.SCRIPT_SELECT_FIND_FLOW_STATUS_BY_STATUS );
ps.setInt( 1, idStatusPrevious );
ps.setInt( 2, idStatus );
rs = ps.executeQuery();
Long count = 0L;
if ( rs != null ) {
while ( rs.next() ) {
count = rs.getLong( 1 );
break;
}
}
LogUtil.logSuccessMethod();
return count > 0L;
} catch ( Exception e ) {
String errorMsg = String
.format( Constants.ERROR_FINALIZED_METHOD, ( e.getMessage() != null ? e.getMessage() : "" ) );
LogUtil.logError( errorMsg, e );
throw new FatalException( errorMsg );
} finally {
rs.close();
ps.close();
}
A ResultSetClosedException could be thrown for two reasons.
1.) You have opened another connection to the database without closing all other connections.
2.) Your ResultSet may be returning no values. So when you try to access data from the ResultSet java will throw a ResultSetClosedException.
It happens also when using a ResultSet without being in a #Transactional method.
ScrollableResults results = getScrollableResults("select e from MyEntity e");
while (results.next()) {
...
}
results.close();
if MyEntity has eager relationships with other entities. the second time results.next() is invoked the ResultSet is closed exception is raised.
so if you use ScrollableResults on entities with eager relationships make sure your method is run transactionally.
"result set is closed" happened to me when using tag <collection> in MyBatis nested (one-to-many) xml <select> statement
A Spring solution could be to have a (Java) Spring #Service layer, where class/methods calling MyBatis select-collection statements are annotated with
#Transactional(propagation = Propagation.REQUIRED)
annotations being:
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
this solution does not require to set the following datasource properties (i.e., in JBoss EAP standalone*.xml):
<xa-datasource-property name="downgradeHoldCursorsUnderXa">**true**\</xa-datasource-property>
<xa-datasource-property name="resultSetHoldability">**1**</xa-datasource-property>