I have a problem when updating data with NetBeans. When I update without changing the id, the error message appears key duplicate '10' for 'primary'
SQL = "update sumber set nama_sumber=?, alamat_sumber=?, kapasitas_sumber=? WHERE id_sumber='"+kodegudang+"'";
ps = conn.prepareStatement(SQL);
ps.setString(1, txt_id.getText());
ps.setString(2, txt_nama.getText());
ps.setString(3, txt_alamat.getText());
ps.setString(4, kapasitasdos.getText());
JOptionPane.showMessageDialog(null, "Sumber Air berhasil Diedit");
ps.executeUpdate();
All the primary key values in a table must be different. I'm guessing that you already have a row with nama_sumber = 10 (or whatever the primary key is). You can check that by connecting to the database directly and running select * from sumber.
Related
Is there any way to detect in Java that a H2 merge into statement was doing insert instead of update?
In both cases the result is the number of affected rows but I need to know if the record was already there and updated or it was just created.
The result is interesting for a Rest service where I want to return 204 instead of 201 - Created.
Yes, there is:
Connection c = DriverManager.getConnection("jdbc:h2:mem:1")) {
Statement s = c.createStatement();
s.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, V INT)");
PreparedStatement ps = c.prepareStatement(
"SELECT ID FROM OLD TABLE (MERGE INTO TEST(ID, V) KEY(ID) VALUES (?, ?))");
ResultSet rs;
ps.setInt(1, 1);
ps.setInt(2, 10);
rs = ps.executeQuery();
System.out.println(rs.next() ? "UPDATE" : "INSERT");
ps.setInt(1, 1);
ps.setInt(2, 20);
rs = ps.executeQuery();
System.out.println(rs.next() ? "UPDATE" : "INSERT");
You need a recent version of H2, however, because historic versions don't support data change delta tables.
In the sample code I used non-standard and non-portable variant of MERGE command for simplicity. You can either use it or its standard-compliant version, you can find syntax of both of them in documentation of H2.
I am trying to update user profile by taking input through a jsp form and storing it into a table in MYSQL Workbench using servlet. I am getting a Syntax Error while updating the table.
ps = (PreparedStatement) con.prepareStatement("UPDATE user SET user_id =?, FName=? , LName=?, City=? , Email=? , Country=? , DOB=?, JobPosition=?, Profile_Picture=? WHERE user_id=123");
ps.setInt(1, UserId);
ps.setString(2, Fname);
ps.setString(3, Lname);
ps.setString(4, City);
ps.setString(5, EmailId);
ps.setString(6, Country);
ps.setDate(7, java.sql.Date.valueOf(DOB));
ps.setString(8, JobPosition);
if (inputStream != null) {
ps.setBlob(9, inputStream);
}
[EDIT]
Error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''techquo'.'user' set user_id =123, FName='Default' , LName='Default', City='' ,' at line 1
This is my SQL query. I am new to this and cannot figure out what's wrong with the syntax. The table name and the name of attributes are correct. I have rechecked. Any help would be appreciated. Thanks!
user is a reserved keyword. see the docs here
try wrapping it in backticks:
ps = (PreparedStatement) con.prepareStatement("Update `user` set user_id =?, FName=? , LName=?, City=? , Email=? , Country=? , DOB=?, JobPosition=?, Profile_Picture=?");
also, there is no where clause, so the update will be applied to all the rows - Probably not what you want.
I am using java to execute some SQL Queries. Some of them are Getting data from one database(A) and storing in a table in another database(B).After process is done i am deleting all data from table in database(B). I am repeating this process every 5 mins.
Code:
String sql = "delete from newtable";
stmt5 = conn.prepareStatement(sql);
stmt5.executeUpdate(sql);
String sql_1 = "select distinct tbl_alm_log_2000000000.Csn, tbl_alm_log_2000000000.IsCleared, tbl_alm_log_2000000000.Id,tbl_alm_log_2000000000.NEType, tbl_alm_log_2000000000.OccurTime, tbl_alm_log_2000000000.hostIP, tbl_alm_log_2000000000.ExtendInfo From fmdb.dbo.tbl_alm_log_2000000000 Where IsCleared = 0";
ResultSet rs = stmt_1.executeQuery(sql_1);
String sql_2 = "insert into newtable (CSN, IsCleared, Id, NEType, OccurTime, hostIP) values(?,?,?,?,?,?)";
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement(sql_2);
final int batchSize = 1000;
int count = 0;
while (rs.next()){
ps.setString(1, rs.getString(1)); //csn
ps.setString(2, rs.getString(2)); //iscleared
ps.setString(3, rs.getString(3));//id
ps.setString(4, rs.getString(4));//netype
ps.setString(5, rs.getString(5));//occurtime
ps.setString(6, rs.getString(6));//hostip
ps.addBatch();
if(++count % batchSize == 0) {
ps.executeBatch();
}
}
ps.executeBatch(); // insert remaining records
conn.commit();
ps.close();
It runs perfectly for 10 -20 runs and then gives "duplicate entry error for "value" in Csn as it is Primary key".
I added Distinct keyword in query and it is still giving this error after 10-20 runs.
Note: I m deleting data from newtable befor start of process so it is always adding in a empty table.
Suggest where i am going wrong.
Looks like you have misunderstanding about how does distinct work. In query with several selected columns it will search for distinct tuples of values, not for distinct Csn column only.
There are different ways how to select distinct values by one column only. It generally depends on particular DBMS you use and logic you want to apply for multiply tuples found for same Csn column values. Consider for instance this question: DISTINCT for only one Column
One of general ideas: select distinct single values for Csn column only, then iterate through this list and select first tuple of values with this Csn value (I don't know is it suitable for you select first tuple or not).
when you insert the data , you can add if not exists not make sure your data is unique ( i considered CSN only column in PK)
if not exists(select 1 from tbl_alm_log_2000000000 where CSN=? )
insert into newtable (CSN, IsCleared, Id, NEType, OccurTime, hostIP) values(?,?,?,?,?,?)
Good evening. Below is my code on adding items in my database
String sql = "Insert into userinfo(firstname,lastname,contactNumber,email,address,username,password,accountType) value (?,?,?,?,?,?,?,?)";
String accountType = (String) jComboBoxAccType.getSelectedItem();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, jTextFieldFistName.getText());
ps.setString(2, jTextFieldLastName.getText());
ps.setString(3, jTextFieldContactNumber.getText());
ps.setString(4, jTextFieldEmail.getText());
ps.setString(5, jTextFieldAddress.getText());
ps.setString(6, jTextFieldUsername.getText());
ps.setString(7, jTextFieldPassword.getText());
ps.setString(8, accountType);
ps.execute();
How would I be able to check if there is already an existing username and password before adding?
Normally, you want the database to enforce such data integrity rules itself. This ensures that the data is correct. You don't want to check at the application-level, because that introduces race conditions (two inserts happening at essentially the same time, where both validate that the table has not duplicates and then both insert the same values).
You can guarantee uniqueness using a unique constraint or unique index (the former is implemented using the latter). This will generate an error when a duplicate value is inserted. It is easy to create:
alter table userinfo add constraint unq_username_password unique (username, password);
That said, normally a user would have only one password, so the constraint would be only on the user name:
alter table userinfo add constraint unq_username unique (username);
You need something like this code
PreparedStatement ps=connection.prepareStatement("select 1 from userinfo where username=? and password=?");
ps.setString(1, jTextFieldUsername.getText());
ps.setString(2, jTextFieldPassword.getText());
ps.execute();
if (ps.getResultSet.next()) {
// So, user and password already in database
}
else {
// Insert value...
}
But, as for me, check the existing same pair of (username,password) during adding new user to database is not a good idea.
There are 3 different ways to perform the checking:
1) Create a query that search if a record with the same username and password exists, something like:
SELECT COUNT(*) as exists FROM userinfo WHERE username = :username AND password = :password
or
SELECT username as exists FROM userinfo WHERE username = :username AND password = :password
So if a duplicate record is found the "exists" field is going to return a value different than 0 or NULL.
2) Just create an unique index for both username and password and when you are trying to insert a duplicated record an error is going to be raised, so you have to use a a "try...catch" statement between the "ps.execute".
3) Adding a subquery that checks if duplicate values exists (See: https://stackoverflow.com/a/3025332/1641558)
You should only change the query as,
Insert ignore into userinfo(firstname,lastname,contactNumber,email,address,username,password,accountType) value (?,?,?,?,?,?,?,?)
I have a requirement where I need to insert mobile number in mysql if and only if the number is is not present.So for this I am first checking if a number is present in mysql using select query .If number is not present then insert.Following is my code
PreparedStatement pt1=con.prepareStatement("select * from registerSmsUsers where mobile='"+mobile+"'");
PreparedStatement pt=con.prepareStatement("insert into registerSmsUsers values(?,?,?)");
pt.setString(1, name);
pt.setString(2, email);
pt.setString(3, mobile);
ResultSet rs1=pt1.executeQuery();
if(rs1.next())
{pt.executeUpdate();}
i dont know whether this is a efficient way or not.Please suggest me a better way then this
Probably the easiest way in mysql is:
insert ignore into registerSmsUsers values(?,?,?)
When assuming you have unique key on mobile
You may check it here: How to 'insert if not exists' in MySQL?
Or here: http://dev.mysql.com/doc/refman/5.6/en/insert.html
Many of the proposed solutions (including yours) have a race condition that can cause a primary key or unique constraint violation. You code also have a possible SQL injection attack by concatenating SQL rather than using prepared statement parameters. Use SELECT...FOR UPDATE.
PreparedStatement ps = con.prepareStatement("SELECT name, email, mobile FROM registerSmsUsers WHERE mobile=? FOR UPDATE",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
ps.setString(1, mobile);
ResultSet rs = ps.executeQuery();
if (rs.next()) { // it exists already
rs.moveToCurrentRow();
rs.updateString(3, mobile);
rs.updateRow();
} else { // it does NOT exist
rs.moveToInsertRow();
rs.updateString(1, name);
rs.updateString(2, email);
rs.updateString(3, mobile);
rs.insertRow();
}
rs.close();
ps.close();
EDIT: Just make sure you have an index on registerSmsUsers.
CREATE INDEX registerSmsUsers_mobile_ndx ON registerSmsUsers(mobile)
or a unique contraint (which implicitly creates an index):
ALTER TABLE registerSmsUsers ADD CONSTRAINT registerSmsUsers_mobile_unq UNIQUE (mobile)
With an index, even with millions of records the update/insert will basically be instant.
EDIT2: Added cursor/result set options.
I think it would be better to create a stored procedure and then in that stored procedure you can first use the IF NOT EXISTS clause to check if the user exists using the select statement. If the user is not present you can insert the user in database.
Something like this:
IF NOT EXISTS(SELECT 1 FROM `registerSmsUsers` WHERE mobile= #mobile) THEN
BEGIN
INSERT INTO
`registerSmsUsers`
(
//column names
)
VALUES
(
//values
);
END;
END IF;
Also there is a INSERT IGNORE statement which you can use like this:
insert ignore into registerSmsUsers values(?,?,?)
if not exists(select * from registerSmsUsers where mobile='232323') <-- will check your mobile no
begin
insert into registerSmsUsers values(?,?,?)
end
This one is also an efficient way to check your method is also working fine but this also can be done
See difference is you will have only one query here
i hope this will help you thanks
[Edit]
Your questions answer
Ya there is a execution time diff between yours and mine query its depends upon a database size what you are using if you are using small size database (probably 1000 people) then you will not see any diff between your query and mine query but if your are using lakhs of users then your will have a performace issues check include execution plan in mysql you will get realtime difference between two
As requested, here is my tweaked version of brettw's answer:
import java.sql.*;
public class MySQLtest {
public static void main(String[] args) {
Connection con;
try {
con = DriverManager.getConnection(
"jdbc:mysql://192.168.1.3/zzzTest?" +
"useUnicode=yes&characterEncoding=UTF-8" +
"&user=root&password=whatever");
String newName = "Gord";
String newEmail = "gord#example.com";
String newMobile = "416-555-1212";
String sql =
"SELECT " +
"id, " +
"name, " +
"email, " +
"mobile " +
"FROM registerSmsUsers " +
"WHERE mobile = ? " +
"FOR UPDATE";
PreparedStatement pst = con.prepareStatement(
sql,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
pst.setString(1, newMobile);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
rs.moveToCurrentRow();
rs.updateString("name", newName);
rs.updateString("email", newEmail);
rs.updateRow();
System.out.println("Existing row updated.");
}
else {
rs.moveToInsertRow();
rs.updateString("name", newName);
rs.updateString("email", newEmail);
rs.updateString("mobile", newMobile);
rs.insertRow();
System.out.println("New row inserted.");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
Note that id is the Primary Key for the table: int(11) NOT NULL AUTO_INCREMENT