I'm inserting some data into a mySql database. For some unknown reason the data is not being inserted into my table. This worked fine with SQLITE.
Here is my code:
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, username, password);
String query1 = "insert into Project (uniqueid,name,address,startingdate,estcompletion,engname) values(?,?,?,?,?,?)";
String query2 = "insert into EngineerData (UniqueId,Name,Password) values(?,?,?)";
String query3 = "insert into " +tableName +" (UniqueId,Category,Item,EstimatedQuantity,Unit,UnitPrice,TotalPrice,TotalSpent) values(?,?,?,?,?,?,?,?)";
String query4 = "insert into ProjectImages (uniqueId, Path) values(?,?)";
PreparedStatement pst1= conn.prepareStatement(query1);
PreparedStatement pst2 = conn.prepareStatement(query2);
PreparedStatement pst3 = conn.prepareStatement(query3);
PreparedStatement pst4 = conn.prepareStatement(query4);
pst1.setInt(1, uniqueID);
pst1.setString(2, projectName.getText());
pst1.setString(3, address.getText());
pst1.setString(4, day1.getText()+"/"+month1.getText()+"/"+year1.getText());
pst1.setString(5, day2.getText()+"/"+month2.getText()+"/"+year2.getText());
pst1.setString(6, engineerName.getText());
pst2.setInt(1, uniqueID);
pst2.setString(2, engineerName.getText());
pst2.setString(3, engineerPassword.getText());
try{
for (int j = 0; j < table.getRowCount(); j++ ){
pst3.setInt(1, uniqueID);
pst3.setString(2, table.getValueAt(j, 0).toString());
pst3.setString(3, table.getValueAt(j, 1).toString());
pst3.setString(4, table.getValueAt(j, 2).toString());
pst3.setString(5, table.getValueAt(j, 3).toString());
pst3.setString(6, table.getValueAt(j, 4).toString());
pst3.setString(7, table.getValueAt(j, 5).toString());
pst3.setDouble(8, 0.0);
pst3.execute();
}}catch(Exception e3){
/*JOptionPane.showMessageDialog(null, e3);
*
*/
}
pst4.setInt(1, uniqueID);
pst4.setString(2, null);
pst1.execute();
pst2.execute();
pst4.execute();
System.out.println(pst1.toString());
System.out.println(pst2.toString());
pst1.close();
pst2.close();
pst3.close();
pst4.close();
conn.close();
}
You should leave out auto generated column "uniqueID" and rewrite your code.
Ex.
String query4 = "insert into ProjectImages (Path) values(?)";
Another approach - passing null value for auto generated column. Ex.
String query4 = "insert into ProjectImages (uniqueId, Path) values(null,?)";
Without the stack trace it might be difficult to get where this is not working. It might be a INDEX constraint exception, a null pointer exception, ... But, I'd suggest to format differently the date, instead of
day1.getText()+"/"+month1.getText()+"/"+year1.getText()
I'd use
year1.getText()+"-"+month1.getText()+"-"+day1.getText()
(check the MySQL documentation and especially the STR_TO_DATE() function, but you probably don't need it).
And also there's room to improve your code (following Rajesh's comment):
While probably you're using Java 7 or above, I'd add the try-with statement for the connection;
Catching Exception is generally bad practice, I'd go for a fine-grain try-catch with SQLException, ...
I can't see any transaction strategy in place. I'd be worried while some of the pst?.execute() works fine and another doesn't, leaving your database in an inconsistent state.
Related
I'm trying to fix this one for a while but can't find the or fix the code. The error triggered when I add a auto generated 'id' which is in method.
private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/inventory?useTimezone=true&serverTimezone=UTC", "root", "ichigo197328");
int row = jTable1.getSelectedRow();
String value = (jTable1.getModel().getValueAt(row, 0).toString());
String sql = "UPDATE category SET category_name = ? WHERE category_id = "+ value;
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, CategoryNameField.getText());
pstmt.executeUpdate();
DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
model.setRowCount(0);
JOptionPane.showMessageDialog(null, "Record Updated Successfully ");
DisplayTable();
conn.close();
}
catch(Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
You are correctly using a prepared statement, but you should be using a positional parameter in the WHERE clause instead of concatenation:
String sql = "UPDATE category SET category_name = ? WHERE category_id = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, CategoryNameField.getText());
pstmt.setString(2, value);
pstmt.executeUpdate();
The exact cause of the error has to do with your WHERE clause comparing the category_id string column against an unescaped string literal, e.g.
WHERE category_id = some_value -- should be 'some_value'
SQL will interpret some_value as referring to a column, table, etc. name. By using a prepared statement (which you alreary are doing), you let the database handle the proper escaping of the values.
I am trying to add two strings on two separate columns columns of my database using Java but I'm not sure what I am doing wrong. The code I am using
try{
Connection conn = DriverManager.getConnection(
"jdbc:ucanaccess://C:/Users/nevik/Desktop/databaseJava/Employee.accdb");
Statement st = conn.createStatement();
String sql = "Select * from Table2";
ResultSet rs = st.executeQuery(sql);
rs.updateString("user", user);
rs.updateString("pass", pass);
rs.updateRow();
}
catch(SQLException ex){
System.err.println("Error: "+ ex);
}
The first column on my database is user and the next one is pass. I am using UCanAccess in order to access my database.
This is how you normally update a row in java:
String query = "update Table2 set user = ?, pass= ?";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt (1, user);
preparedStmt.setString(2, pass);
// execute the java preparedstatement
preparedStmt.executeUpdate();
First of, you've not updated the position of the current cursor in the ResultSet, which means that it's pointing to nothing...
You could use...
if (rs.next()) {
rs.updateString("user", user);
rs.updateString("pass", pass);
rs.updateRow();
}
But this assumes two things...
You have a database that supports updating values in the ResultSet and
You want to update the existing values.
To insert a value into the database, you should be using the INSERT command, for example...
try(Connection conn = DriverManager.getConnection(
"jdbc:ucanaccess://C:/Users/nevik/Desktop/databaseJava/Employee.accdb")) {
try (PreparedStatement stmt = conn.prepareStatement("INSERT into Table2 (user, pass) VALUES (?, ?)") {
stmt.setString(1, user);
stmt.setString(2, pass);
int rowsUpdated = stmt.executeUpdate();
}
}
catch(SQLException ex){
System.err.println("Error: "+ ex);
}
You might like to take some time to go over a basic SQL tutorial and the JDBC(TM) Database Access trail
As a side note...
You should not be storing passwords in Strings, you should keep them in char arrays and
You should not be storing passwords in the database without encrypting them in some way
#guevarak12
About the original question (how to use updatable ResultSet):
your code is wrong, you have to move the cursor in the right position.
In particular, if you are inserting a new row you have to call rs.moveToInsertRow(); before rs.updateString("user", user).
If you are updating an existent row, you have to move the cursor calling rs.next() and so reach the row to update.
Also you have to create the Statement in a different way:
Statement st =conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
See junit examples in the UCanAccess source distribution, class net.ucanaccess.test.CrudTest.
All other comments seem to be correct.
I have been searching and trying different stuff for awhile, but have not found an answer. I'm trying to make a connection to sql using JDBC from eclipse. I am having trouble when I need to select a string in the database. If I use:
Select name from data where title = 'mr';
That works with terminal/command line but when I try to use eclipse where I use
statement sp = connection.createstatement();
resultset rs = sp.executequery("select name from data where title = '" + "mr" + "'");
It does not give me anything while the terminal input does. What did I do wrong in the eclipse? Thanks
Heres a part of the code. Sorry, its a bit messy, been trying different things.
private boolean loginChecker(String cid, String password) throws SQLException{
boolean check = false;
PreparedStatement pstatment = null;
Statement stmt = null;
//String query = "SELECT 'cat' FROM customer";
String query = "select '"+cid+"' from customer where password = '"+password+"'";
try {
System.out.println("in try......");
//stmt = con.createStatement();
//ResultSet rs = stmt.executeQuery(query);
PreparedStatement prepStmt = con.prepareStatement(query);
ResultSet rs = prepStmt.executeQuery();
//System.out.print(rs.getString("cid"));
while(rs.next()){
check = true;
System.out.print(rs.getString("cid"));
}
} catch (SQLException e ) {
e.printStackTrace();
} finally {
if (stmt != null) {
//stmt.close();
}
}
return check;
}
Second try on a simpler query:
public List<Object> showTable() {
List<Object> result = new ArrayList<Object>();
String name = "bob";
try
{
PreparedStatement preStatement = con.prepareStatement("select total from test where name = ?");
preStatement.setString(1, name);
ResultSet rs1 = preStatement.executeQuery();
while(rs1.next()){
System.out.println("there");
System.out.println(rs1.getInt("total"));
}
}
catch (SQLException ex)
{
System.out.print("Message: " + ex.getMessage());
}
return result;
}
Remove the quotes around the column name.
String query = "select "+cid+" from customer where password = '"+password+"'";
You've not mentioned which database you're working with but many databases like Oracle change the column case to upper case unless they're quoted. So, you only quote table columns if that's how you had created them. For example, if you had created a table like
CREATE TABLE some_table ( 'DoNotChangeToUpperCase' VARCHAR2 );
Then you would have to select the column with quotes as well
SELECT 'DoNotChangeToUpperCase' FROM some_table
But, if you didn't create the table using quotes you shouldn't be using them with your SELECTs either.
Make sure you are not closing the ResultSet before you are trying to use it. This can happen when you return a ResultSet and try to use it elsewhere. If you want to return the data like this, use CachedRowSet:
CachedRowSet crs = new CachedRowSetImpl();
crs.populate(ResultSet);
CachedRowSet is "special in that it can operate without being connected to its data source, that is, it is a disconnected RowSet object"
Edit: Saw you posted code so I thought I add some thoughts. If that is your ACTUAL code than the reason you are not getting anything is because the query is probably not returning anything.
String query = "select '"+cid+"' from customer where password = '"+password+"'";
This is wrong, for two reasons. 1) If you are using prepared statements you should replace all input with '?' so it should look like the following:
String query = "select name from customer where password = ?";
Then:
PreparedStatement prepStmt = con.prepareStatement(query);
prepStmt.setString(1, password);
ResultSet rs = prepStmt.executeQuery();
2)
System.out.print(rs.getString("cid"));
Here are are trying to get the column named "cid", when it should be the name stored in cid. You should actually never be letting the user decide what columns to get, this should be hardcoded in.
This is the code block in question:
String sq = "INSERT INTO survey (session_id, character_id, timestamp) VALUES (?,?,?)";
PreparedStatement sadd = conn.prepareStatement(sq, PreparedStatement.RETURN_GENERATED_KEYS);
sadd.setLong(1, sessionId);
sadd.setLong(2, character_id);
sadd.setString(3, dateTime);
int affectedrows = sadd.executeUpdate();
//get the ID
long resultId = 0;
ResultSet key = sadd.getGeneratedKeys();
if (key.next()) {
resultId = key.getLong(1);
}
This query worked fine without the PreparedStatement.RETURN_GENERATED_KEYS option, but when I add it suddenly executeUpdate() throws an exception:
com.microsoft.sqlserver.jdbc.SQLServerException: A result set was generated for update.
If I take the PreparedStatement.RETURN_GENERATED_KEYS out, it works again fine. Out of frustration, I changed executeUpdate() to executeQuery() just to see if I could get the key back and got an exception that it can't get keys because the statement must be executed first.
How can I get the generated key? I am using SQL Server 2008 and the latest JDBC driver.
Looks like a driver bug to me.
You should try a newer 4.0 driver from here -> http://www.microsoft.com/download/en/details.aspx?id=11774
If that does not work, one work around would be to create an 'insert' stored procedure and return the generated id as a stored procedure output parameter.
Looks like a bug. Could you give the uglier alternative a try?
String dateTimeS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm").format(dateTime);
String sq = "INSERT INTO survey (session_id, character_id, timestamp) "
+ "VALUES (" + sessionId + ", " + character_id + ", '" + dateTimeS + "')";
Statement sadd = conn.createStatement();
int affectedrows = sadd.executeUpdate(sq, Statement.RETURN_GENERATED_KEYS);
I'm having the same issue with the 4.0 & 4.1 JDBC drivers. After a while an insert on a autonumber table would give a "A result set was generated for update." at random. I use connection pooling and somehow the driver can get into a state where executeUpdate in combination with Statement.RETURN_GENERATED_KEYS doesn't work anymore. I found out that in this state an executeQuery does the trick, but in the initial state executeQuery does not work. This lead me to the following workaround:
PreparedStatement psInsert = connection.prepareStatement("INSERT INTO XYZ (A,B,C) VALUES(?,?,?)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = null;
try {
psInsert.setString(1, "A");
psInsert.setString(2, "B");
psInsert.setString(3, "C");
Savepoint savePoint = connection.setSavepoint();
try {
psInsert.executeUpdate();
rs = psInsert.getGeneratedKeys();
} catch (SQLServerException sqe)
{
if (!sqe.getMessage().equals("A result set was generated for update."))
throw sqe;
connection.rollback(savePoint);
rs = psInsert.executeQuery();
}
rs.next();
idField = rs.getInt(1);
} finally {
if(rs != null)
rs.close();
psInsert.close();
}
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);
}