String sql = "UPDATE `test`.`books` SET ? = ? WHERE `isbn` = ?;";
PreparedStatement ps = null;
ps = conn.prepareStatement(sql);
ps.setString(1,whatToUp);
ps.setString(2, data);
ps.setString(3, isbn);
ps.executeUpdate(sql);
System.out.println("Statement executed");
conn.close();
Error say that something is wrong with query . I am usign MySQL 5.6.
I copied the statement from the workbench 6.0 and just placed ? wherever I needed.
Even this Gives an error:
String sql = "UPDATE `test`.`books` SET `title` = ? WHERE `isbn` = ?;";
PreparedStatement ps = null;
ps = conn.prepareStatement(sql);
ps.setString(1, data);
ps.setString(2, isbn);
ps.executeUpdate(sql);
System.out.println("Statement executed");
conn.close();
You can build the query dynamically
String sql = "UPDATE `test`.`books` SET " + whatToUp + " = ? WHERE `isbn` = ?;";
PreparedStatement ps = null;
ps = conn.prepareStatement(sql);
ps.setString(1, data);
ps.setString(2, isbn);
ps.executeUpdate(); // you need to use the overloaded method without an argument
Note that you are then vulnerable to SQL injection.
If for some reason that is wrong, remove all the quotes.
String sql = "UPDATE test.books SET " + whatToUp + " = ? WHERE isbn = ?;";
If that doesn't work, then your schema doesn't match. That's up to you.
In my rush to answer I didn't see you were using
ps.executeUpdate(sql);
This method's javadoc says
Note:This method cannot be called on a PreparedStatement or
CallableStatement.
You have to use
ps.executeUpdate();
since you've already provided the sql statement to the method.
All of this would've been solved extremely quickly if you had just provided the exception stack trace. Consider that next time you ask a question
The problem is that you are calling executeUpdate(String) on a PreparedStatement, for which the documentation says:
SQLException - [...], the method is called on a PreparedStatement or CallableStatement
You need to use executeUpdate() (so without parameters) to execute a PreparedStatement. The reason is: a prepared statement already knows its query (the one it was created with), so it makes no sense to provide a query when executing it.
Note that the MySQL implementation is not entirely conforming to JDBC. It actually does allow executing with a String here, but it causes a syntax error because of the parameter placeholders.
Your first piece of code will never work, because parameters can only be used in places of values, not in places where object names (like table names) are expected.
#SotiriosDelimanolis gave you the answer.
Just build the SQL String differently
Stringbuilder sql = new Stringbuilder("UPDATE test.books SET ");
sql.append(whatToUp);
sql.append(" = ? WHERE isbn = ?");
PreparedStatement ps = null;
ps = conn.prepareStatement(sql.toString());
ps.setString(1, data);
ps.setString(2, isbn);
ps.executeUpdate(sql.toString());
System.out.println("Statement executed");
conn.close();
Related
When I debug, I get this error :
Column 'place1' not found.
I was able to verify that it has column place1 in sql.
Is it because I can not have two database connection in one function? I am unsure on how to further debug the problem.
Case.java
System.out.println("The highest value is "+highest+"");
System.out.println("It is found at index "+highestIndex+""); // until now it works fine
String sql ="Select Day from menu where ID =?";
DatabaseConnection db = new DatabaseConnection();
Connection conn =db.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, highestIndex);
ResultSet rs = ps.executeQuery();
if (rs.next())
{
int kb=rs.getInt("Day");
System.out.println(kb);
if(kb==k) // k is a value getting from comboBox
{
String sql1 ="Select * from placeseen where ID =?";
DatabaseConnection db1 = new DatabaseConnection();
Connection conn1 =db1.getConnection();
PreparedStatement ps1 = conn.prepareStatement(sql);
ps.setInt(1, highestIndex);
ResultSet rs1 = ps.executeQuery();
if (rs1.next())
{
String aaa=rs1.getString("place1");
String bbb=rs1.getString("place2");
Tourism to =new Tourism();
to.setPlace1(aaa);
to.setPlace2(bbb);
DispDay dc=new DispDay();
}
ps1.close();
rs1.close();
conn1.close();
}
else
{
System.out.print("N");
System.out.println("Sorry!!!");
}
}
ps.close();
rs.close();
conn.close();
Trace your code to see where you're getting the data. The error is on this line:
String aaa=rs1.getString("place1");
Where does rs1 come from?:
ResultSet rs1 = ps.executeQuery();
Where does ps come from?:
PreparedStatement ps = conn.prepareStatement(sql);
Where does sql come from?:
String sql ="Select Day from menu where ID =?";
There's no column being selected called place1. This query is only selecting a single column called Day.
Maybe you meant to get the result from the second prepared statement?:
ResultSet rs1 = ps1.executeQuery();
There are probably more such errors. Perhaps several (or many) more. Because...
Hint: Using meaningful variable names will make your code a lot easier to follow. ps, ps1, rs1, etc. are very easy to confuse. Name variables by the things they conceptually represent and your code starts to read like a story which can be followed. Variable names like daysQuery and daysResults and placesResults make it more obvious that something is wrong when you try to find a "place" in a variable which represents "days".
In your second query:
PreparedStatement ps1 = conn.prepareStatement(sql);
you are accidentally using the variable sql instead of your previously defined sql1. Replace it and it will be ok.
I'm new to using Oracle so I'm going off what has already been previously answered in this SO question. I just can't seem to get it to work. Here's the statement that I'm using:
declare
lastId number;
begin
INSERT INTO "DB_OWNER"."FOO"
(ID, DEPARTMENT, BUSINESS)
VALUES (FOO_ID_SEQ.NEXTVAL, 'Database Management', 'Oracle')
RETURNING ID INTO lastId;
end;
When I call executeQuery the PreparedStatement that I have made, it inserts everything into the database just fine. However, I cannot seem to figure out how to retrieve the ID. The returned ResultSet object will not work for me. Calling
if(resultSet.next()) ...
yields a nasty SQLException that reads:
Cannot perform fetch on a PLSQL statement: next
How do I get that lastId? Obviously I'm doing it wrong.
make it a function that returns it to you (instead of a procedure). Or, have a procedure with an OUT parameter.
Not sure if this will work, since I've purged all of my computers of anything Oracle, but...
Change your declare to:
declare
lastId OUT number;
Switch your statement from a PreparedStatement to a CallableStatement by using prepareCall() on your connection. Then register the output parameter before your call, and read it after the update:
cstmt.registerOutParameter(1, java.sql.Types.NUMERIC);
cstmt.executeUpdate();
int x = cstmt.getInt(1);
I tried with Oracle driver v11.2.0.3.0 (since there are some bugs in 10.x and 11.1.x, see other blog). Following code works fine:
final String sql = "insert into TABLE(SOME_COL, OTHER_COL) values (?, ?)";
PreparedStatement ps = con.prepareStatement(sql, new String[] {"ID"});
ps.setLong(1, 264);
ps.setLong(2, 1);
int executeUpdate = ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next() ) {
// The generated id
long id = rs.getLong(1);
System.out.println("executeUpdate: " + executeUpdate + ", id: " + id);
}
When you prepare the statement set the second parameter to RETURN_GENERATED_KEYS. Then you should be able to get a ResultSet off the statement object.
You can use Statement.getGeneratedKeys() to do this. You just need to make sure to tell JDBC what columns you want back using one of the method overloads for that, such as the Connection.prepareStatement overload here:
Connection conn = ...
PreparedStatement pS = conn.prepareStatement(sql, new String[]{"id"});
pS.executeUpdate();
ResultSet rS = pS.getGeneratedKeys();
if (rS.next()) {
long id = rS.getLong("id");
...
}
You don't need to do the RETURNING x INTO stuff with this, just use the basic SQL statement you want.
Are you doing that in a stored procedure ? According to this Oracle document, it won't work with the server-side driver.
The Oracle server-side internal driver does not support
the retrieval of auto-generated keys feature.
I have created a database connection with SQLite using JDBC in Java. My SQL statements execute properly, but sometimes I get the following error while I use conn.commit():
java.sql.SQLException: SQL logic error or missing database
Can anyone please help me how to avoid this type of problem. Is there a better approach of calling JDBC programs?
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:/home/Data/database.db3");
conn.setAutoCommit(false);
String query = "Update Chits set BlockedForChit = 0 where ServerChitID = '" + serverChitId + "' AND ChitGatewayID = '" + chitGatewayId + "'";
Statement stmt = conn.createStatement();
try {
stmt.execute(query);
conn.commit();
stmt.close();
stmt = null;
}
Can your variables serverChitId & chitGatewayId contain characters that would corrupt the SQL? It is usually safer to use PreparedStatements:
PreparedStatement ps = conn.prepareStatement("Update Chits set BlockedForChit = 0 where ServerChitID = ? AND ChitGatewayID = ?");
ps.setString(1, serverChitId);
ps.setString(2, chitGatewayId);
ps.executeUpdate();
This way the JDBC driver is responsible for making sure the necessary escapes are made to the strings.
Try setting conn.setAutoCommit to true. Also you need to delete conn.commit();.
If you are doing this inside of a function, make your function synchronized.
It's even more better if you use PreparedStatement instead of Statement.
All this is happening because sometimes you are trying to connect and modify your database at a same time and since the last connection hasn't commited yet, it throws that exception. When you set it to autoCommit it will handle the flow by itself.(it was really painful for me cause it says nothing more, I read all of the org.sqlite.DB files to find this out)
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:/home/Data/database.db3");
conn.setAutoCommit(true);
PreparedStatement ps = "Update Chits set BlockedForChit = 0 where ServerChitID = ? AND ChitGatewayID = ? ";
ps.setString(1, serverChitId);
ps.setString(2, chitGatewayId);
try {
ps.executeUpdate();
}
I am working with a Java prepared statement that gets data from an Oracle database. Due to some performance problems, the query uses a "virtual column" as an index.
The query looks like this:
String status = "processed";
String customerId = 123;
String query = "SELECT DISTINCT trans_id FROM trans WHERE status = " + status + " AND FN_GET_CUST_ID(trans.trans_id) = " + customerId;
Connection conn = getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(query);
ps.execute();
...
} catch (...)
This does not work. Having the function as part of the where clause causes a SQLException. I am aware of CallableStatement, and know I could use that first and then concatenate the results. However, this table uses FN_GET_CUST_ID(trans_id) as part of it's index. Is there a way to use a prepared statement with a database function as a query parameter?
Never concatenate arguments for the SQL into the String. Always use placeholders (?) and setXxx(column, value);.
You'll get the same error if you'd run the SQL in a your favorite DB tool. The problem is that Oracle can't use the function for some reason. What error code do you get?
If Customer ID is numeric keep in int not in String. Then try doing the following:
String query = "SELECT DISTINCT trans_id FROM trans WHERE status = ? AND FN_GET_CUST_ID(trans.trans_id) = ?";
ps = conn.prepareStatement(query);
ps.setString(1, status);
ps.setInt(2, customerId);
ps.execute();
Besides other benefits of prepared statement you won't have to remember about string quotations (this causes your error most likely) and escaping of the special characters.
At the first glance, the query seems to be incorrect. You are missing an apostrophe before and after the usage of status variable (assuming that status is a varchar column).
String query = "SELECT DISTINCT trans_id FROM trans
WHERE status = '" + status + "' AND FN_GET_CUST_ID(trans.trans_id) = " + customerId;
EDIT: I am not from java background. However, as #Aron has said, it is better to use placeholders & then use some method to set values for parameters to avoid SQL Injection.
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);
}