This question already has answers here:
Too many auto increments with ON DUPLICATE KEY UPDATE
(2 answers)
Closed 8 years ago.
I use this code , in first time it works but after ,I have an error (java.sql.sqlexception duplicate entry '1' for key 'primary')and (a) represent the primary key (auto-increment), please help.
public int a;
String url = "jdbc:mysql://localhost:3306/joebdd";
String driver = "com.mysql.jdbc.Driver";
String user = "root";
String pass = "12345";
try {
Class.forName(driver).newInstance();
Connection con = (Connection) DriverManager
.getConnection(url, user, pass);
Statement st = (Statement) con.createStatement();
ResultSet rs1 = (ResultSet) st
.executeQuery("select count(*) from Bill");
if (rs1.next()) {
if (rs1.getInt(1) == 0) {
a = 0;
}
if (rs1.getInt(1) == 1) {
a = 1;
}
else {
a = rs1.getInt(1);
}
st.executeUpdate("insert into Bill values('"
+ a
+ "','"
+ jTextField2.getText()
+ "','"
+ jLabel7.getText()
+ "','"
+ jTextPane1.getText()
+ "','"
+ Integer.parseInt(jTextField1
.getText()) + "')");
}
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
If a is autoincrement, then you don't need to insert it in the sql query.
No need to insert a value in the auto-incremented field. Use
INSERT INTO Bill (field2, field3, field4, field5) VALUES (...);
Current style is very unsafe. Use a PreparedStatement to be safe from SQL Injection attacks. Refer to this article for how:https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
Related
I'm trying to create an api so I can use it to whatever project I need to create. I'm still new to java so I'm sorry in advance for the wrong codes. Anyways, I've got here this code that has the CRUD statements (except for Read/Retrieve).
import java.sql.*;
public class KitApiNew {
public static void main(String[] args) throws SQLException {
Connection dbConnection = null;
PreparedStatement PSInsert = null;
PreparedStatement PSUpdate = null;
PreparedStatement PSDelete = null;
PreparedStatement PSStatement = null;
String DBTable = "fruits";
String DBColumnSet = "fruit";
String DBID = "23";
String DBColumnSingle = "fruit";
String DBChoice ="insert";
String DBCS = "";
String insertTable = "INSERT INTO " + DBTable + "(" +DBColumnSet+ ")" + "VALUES" + "(?)";
String updateTable = "UPDATE " + DBTable + " SET " + DBColumnSingle + " = ?" + " WHERE id = ?";
String deleteTable = "DELETE FROM " + DBTable + " WHERE id = ?";
String statementTable = "INSERT INTO fruits(fruit) VALUES('grapes')";
try{
dbConnection = getDBConnection();
dbConnection.setAutoCommit(false);
if(DBChoice.equals("insert")){
//for insert
PSInsert = dbConnection.prepareStatement(insertTable);
PSInsert.setString(1, "Orange");
PSInsert.executeUpdate();
dbConnection.commit();
}
if(DBChoice.equals("update")){
//for update
PSUpdate = dbConnection.prepareStatement(updateTable);
PSUpdate.setString(1, "Apple");
PSUpdate.setString(2, DBID);
PSUpdate.executeUpdate();
dbConnection.commit();
}
if(DBChoice.equals("delete")){
//for delete
PSDelete = dbConnection.prepareStatement(deleteTable);
PSDelete.setString(1, DBID);
PSDelete.executeUpdate();
dbConnection.commit();
}
if(DBChoice.equals("statement")){
//for statement
PSStatement = dbConnection.prepareStatement(statementTable);
PSStatement.executeUpdate();
dbConnection.commit();
}
System.out.println("Success!");
}catch(SQLException e){
System.out.println("Error occured " + e.toString());
dbConnection.rollback();
}
finally{
if(PSInsert !=null){
PSInsert.close();
}
if(PSUpdate != null){
PSUpdate.close();
}
if(dbConnection != null){
dbConnection.close();
}
}
}
private static Connection getDBConnection(){
Connection con = null;
try{
Class.forName("com.mysql.jdbc.Driver");
}catch(ClassNotFoundException e){
System.out.println("Error 1 : " + e.getMessage());
}
try{
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/bongbong","root","");
}catch(SQLException e){
System.out.println("Error 2 : " + e.getMessage());
}
return con;
}
}
Oh by the way,
The values of the variables are currently temporary. I'll be changing them later to whatever they're going to be catching. I'm referring to these:
String DBTable = "fruits";
String DBColumnSet = "fruit";
String DBID = "23";
String DBColumnSingle = "fruit";
String DBChoice ="insert";
String DBCS = "";
and this
String statementTable = "INSERT INTO fruits(fruit) VALUES('grapes')";
Problem
What I really need help from is with the ? thing from the first code I posted after the VALUES word inside the String insertTable. I want it so that when I place a column amount in my interface then it'll add more ? in accordance with what was inputted (I also want it to add another PSInsert.setString(n, "value") with n+1 in accordance with the column amount inputted if it's possible). Can anyone tell me how to? I'm really new to java and I'm still a student studying at his best.
I want it to add those ? thing because what if I add more columns or if I use another table with more columns other than my fruits table. (I want it so that whatever I'm going to place in DBColumnSet --with columns separated by comma --will also relate to how many ? are going to be placed).
Oh by the way, it's a general api so I can't provide an interface.
I am a beginner in android development. This is a part of my sign up code in my first android studio app: The code is going into catch right after the first execute query line and not executing my second query. If i check the Database a user is added but not a fan.
Any idea why? Any help is appreciated.
try {
Connection con = connectionClass.CONN();
if (con == null) {
z = "Error in connection with SQL server";
} else {
Statement stmt = con.createStatement();
String query1 = "INSERT INTO Usertb Values ('" + userid + "', '" + Password + "', '" + 1 + "')";
stmt.executeQuery(query1);
String query = "INSERT INTO Fan Values ('" + FirstName + "', '" + LastName + "','" + Age + "', '" + Email + "', '"
+ null + "', '" + i + "', '" + null + "')";
rs = stmt.executeQuery(query);
if (rs.next()) {
z = "Sign Up successfull";
isSuccess = true;
}
}
} catch (Exception ex) {
isSuccess = false;
z = "Exceptions";
}
One has to use executeUpdate (INSERT/UPDATE) instead of executeQuery.
String sql = "INSERT INTO Usertb(userid, passw, n) VALUES (?, PASSWORD(?), ?)";
try (PreparedStatement stmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, userName);
stmt.setString(2, password);
stmt.setInt(3, 1);
int updateCount = stmt.executeUpdate(query1); // 1 when 1 record inserted
if (updateCount != 0) {
// If you want to use an autincrement primary key:
try (ResultSet rsKeys = stm.getGeneratedKeys()) {
if (rsKeys.next()) {
long id = rsKeys.getLong(1);
}
}
}
} // Closes stmt
Furthermore it is very important to use prepared statements to prevent SQL injection. It also takes care of single quotes and backslash in the strings.
Additionally there is shown how to use AUTOINCR fields, to retrieve a database generated key, for example for the second INSERT.
For the second use a new PreparedStatement.
Passwords should better be stored encrypted in the database, should someone steal the data. You might look into that subject. My solution is quite minimal, look for seeding and other encryption functions.
I am trying to read from a mysql table and I am doing the following:
protected void pushRegisteredStudentsData() {
try {
conn = (Connection) DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
String userID = "SELECT * FROM STUDENT";
rs = stmt.executeQuery(userID);
while (rs.next()) {
int id = rs.getInt("ID");
this.studentID = id;
String insertSql = "INSERT INTO REGISTEREDSTUDENTS(StudentID, ModuleCode) VALUES ('" + studentID + "', + '"
+ this.moduleCode + "')";
System.out.println("Inserting into REGISTEREDSTUDENTS.. [" + id + "]" + "[" + this.moduleCode + "]");
stmt.executeUpdate(insertSql);
}
} catch (SQLException e) {
}
}
..but for some reason,
while (rs.next()) {
int id = rs.getInt("ID");
always returns the same ID, even though the table has different ID's on every line!
Does anyone have an idea why that might be?
Thank you in advance! :(
EDIT:
I was using a single statement to execute 2 updates, which was causing the problem!
It is a bit weird that it returns always the same value because it should only return the first value ONCE.
If you print the stacktrace instead of just catching the exception and doing nothing, you will see that it will print something like:
java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:794)
You are using THE SAME statement for a Select and then for an Insert. This causes the resultSet that is "attached" to the Statement to close because it is not supposed to be used again.
It can be easily fixed by creating another statement:
String insertSql = "INSERT INTO REGISTEREDSTUDENTS(StudentID, ModuleCode) VALUES ('" + studentID + "', + '"
+ this.moduleCode + "')";
System.out.println("Inserting into REGISTEREDSTUDENTS.. [" + id + "]" + "[" + this.moduleCode + "]");
Statement stmt2 = conn.createStatement();
stmt2.executeUpdate(insertSql);
String sSQL = "select RFC,Contraseña from Administradores where RFC='" + txtUsuario.getText() + "' and Contraseña='" + txtContrasena.getText() + "'";
String[] registros = new String[2];
Try {
conect();
conexion = DriverManager.getConnection("jdbc:sqlite:" + base);
Statement stat = conexion.createStatement();
ResultSet rs = stat.executeQuery(sSQL);
while (rs.next()) {
registros[0] = rs.getString("RFC");
registros[1] = rs.getString("Contraseña");
}
stat.close();
conexion.close();
} catch (SQLException ex)
{
JOptionPane.showMessageDialog(null,"DB connection error");
}
if ((txtContrasena.getText().equals(registros[1])) || (txtUsuario.getText().equals(registros[0]))) {
JOptionPane.showMessageDialog(null, "Access Granted");
Escoger variable = new Escoger();
variable.setVisible(true);
dispose();
} else {
if (txtContrasena.getText() != (registros[1])) {
JOptionPane.showMessageDialog(null, "Incorrect password");
}
}
This...
String sSQL = "select RFC,Contraseña from Administradores where RFC='" +
txtUsuario.getText() + "' and Contraseña='" +
txtContrasena.getText() + "'";
Would automatically suggest it is. Anything that is input into the txtUsuario and txtContrasena could contain valid SQL code that could be executed by the SQL engine of the database.
You should be using:
String sSQL = "select RFC,Contraseña from Administradores where RFC=? and Contraseña=?";
You will then need to change...
Statement stat = conexion.createStatement();
To
PreparedStatement stat = conexion.preapreStatement(sSQL);
stat.bindString(1, txtUsuario.getText());
stat.bindString(2, txtContrasena.getText());
Take a look at Using Prepared Statements for more details
Further, you should never store a password in the database. You should store a hashed version of the password in the database, and to check the password you hash what you're given (securely, https if via web) and compare that hash value with the hash value in the database. Use a secure hash algorithm (not MD5, for example). Better yet, concatenate the username and password and hash that, then use that as the value to store in the database and compare (that way two users with the same password don't hash to the same value).
Yes. Use PreparedStatements instead. Replace the user and password values with placeholders.
String SampleQuery = "SELECT * FROM YourTable WHERE User = ? AND Password = ?";
String UserName = UsernameBox.getText();
String Password = PasswordBox.getText();
PreparedStatement prep = conn.prepareStatement(SampleQuery);
prep.setString(1, UserName);
prep.setString(2, Password);
ResultSet result = prep.executeQuery();
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Update a record if ID exist else Insert values
I am trying to update a value if the record exists else insert the values in the database. However, that is not working. I have written the code below :
NOTE: (Moderators, this is a repeated questions that I asked few mins ago. I am not able to edit previous one. Apologies if any inconvenience. Requesting you to delete.)
<%
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:sqlserver://10.222.10.19:1433", "sa", "admin1");
String empId = request.getParameter("empid");
String fName = request.getParameter("fName");
String lName = request.getParameter("lName");
String sqlCheck = "Select * from [UAP].[dbo].[UAP_EMPLOYEE] where EMP_EMPLOYEE_ID = "empId" ";
PreparedStatement prpStatementCheck = conn.prepareStatement(sqlCheck);
prpStatementCheck.setInt(1, Integer.parseInt(empId));
prpStatementCheck.setString(2, fName);
prpStatementCheck.setString(3, lName);
ResultSet rsCheck=prpStatementCheck.executeQuery();
String check=null;
boolean exists = false;
while(rsCheck.next())
{
Statement stmt = conn.createStatement();
String sql= "UPDATE [UAP].[dbo].[UAP_EMPLOYEE] SET EMP_EMPLOYEE_ID="+empId+", EMP_FNAME='"+fName+"', EMP_LNAME='"+lName+"' WHERE EMP_EMPLOYEE_ID= ?";
stmt.executeUpdate(sql);
exists = true;
}
if(!exists)
{
String sql2 = "INSERT INTO [UAP].[dbo].[UAP_EMPLOYEE] (EMP_EMPLOYEE_ID, EMP_FNAME, EMP_LNAME ) VALUES (?,?,?)";
PreparedStatement prpStatement1 = conn.prepareStatement(sql2);
prpStatement1.setInt(1, Integer.parseInt(empId));
prpStatement1.setString(2, fName);
prpStatement1.setString(3, lName);
prpStatement1.execute();
prpStatement1.close();
}
%>
As EMP_EMPLOYEE_ID is an INTEGER field you will need to use:
prpStatementCheck.setInt(1, Integer.parseInt(empId));
Also, you can remove the quotes around this field for the UPDATE string:
String sql= "UPDATE [UAP_EMPLOYEE] SET EMP_EMPLOYEE_ID=" + empId + ", EMP_FNAME='" + fName+"', EMP_LNAME='" + lName + "' WHERE EMP_EMPLOYEE_ID= " + empId;
Again for prpStatement1:
prpStatement1.setInt(1, Integer.parseInt(empId));