I have a unique key set for a mysql database row so not to insert duplicate entries on a form submit. That works fine, but if there's a duplicate entry the page doesn't load. Instead the user receives the warning: Duplicate entry ''' for key ''
How do I go about turning that error off and loading the page even if there is a duplicate key, while still using the unique key on the row? I tried setting error report to off, but that didn't work.
mysql_query("INSERT INTO user
(formemail,UserIP,Timestamp,LP) VALUES('$email','$userip',NOW(),'$lp') ")
or die(mysql_error());
You need to change your SQL insert to use INSERT ... ON DUPLICATE KEY UPDATE Syntax so that the error isn't generated in the first place.
Don't try to hide the symptom, treat the problem.
Also, I must point out that the mysql library is being deprecated and should not be used for new code, you should, at the least, use mysqli or, preferably PDO. There is a good tutorial on PDO here if you are interested in learning.
Related
I'm wondering if there's an easy way to check if an INSERT statement triggers a conflict due to a unique index on a MySQL field while performing the INSERT.
For example, say I'm adding a user to a database, and username is a unique index:
$sql = new MySQLi(...);
$res = $sql->query('INSERT INTO `users` (`username`) VALUES ("john_galt");');
A user named john_galt already exists, so the INSERT won't be performed. But how can I best respond to the user with a meaningful error (i.e. A user with that username already exists; please choose a unique name.)?
I thought of a couple things, like checking if insert_id is set -- which it shouldn't be if the query generated an error. But that error could be anything.
Similarly, I could check to see if $sql->error is not empty, except, again, that could be anything as well -- a syntax error, or a malformatted value, or whatever. Obviously I'm not going to print out the actual MySQL error for the end user.
The two solutions I can think of are:
Before running the INSERT, run a SELECT TRUE FROM ``users`` WHERE ``username`` = "john_galt"; to see if the username already exists in the database, but I feel like I added a unique constraint to the field so that I wouldn't have to do this -- kinda defeats the purpose otherwise.
strpos($sql->error, 'Duplicate entry') === 0 -- seems horribly hackish.
Is there a better method for determining this using PHP's MySQLi class?
You can use errno to get the returned error code and use that, for example:
if($sql->errno === 1062) {
//do something
}
Here's a list of error codes for MySQL 5.5: http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
I thought the most efficient way was to create a UNIQUE field on the table instead of selecting to check for existing values before doing anything else but this makes use of two queries. Instead with a UNIQUE field only one query is necessary because MySQL checks for you. The problem is that duplicate entry errors cause an internal server error which I cannot recover from in PHP. What do you guys suggest, what is the best way to avoid duplicate entries in a PHP & MySQL application?
Use ON DUPLICATE KEY
INSERT INTO someTable (id, amount) VALUES ($to_uid, $send_amount)
ON DUPLICATE KEY UPDATE amount = amount + $send_amount
https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
2) You can catch the duplicate key exception. PDO example:
try{
$stmt->execute(...);
}
catch(PDOException $e){
if($e->errorInfo[1] == 1062){
// Mysql returned 1062 error code which means a duplicate key
}
}
You could use REPLACE INTO for your query, it will try an insert first and than it will delete the row with the same ID and replace it.
FOUND THE SOLUTION!
CodeIgniter requires the setting
$db['default']['stricton'] = TRUE;
an explicitly calling
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
In order for MySQL to throw exceptions. The exceptions must also be caught.
You can use INSERT IGNORE to prevent updating a row and prevent an exception from being thrown if row already exists.
https://dev.mysql.com/doc/refman/5.5/en/insert.html
If you use the IGNORE keyword, errors that occur while executing the
INSERT statement are ignored. For example, without IGNORE, a row that
duplicates an existing UNIQUE index or PRIMARY KEY value in the table
causes a duplicate-key error and the statement is aborted. With
IGNORE, the row still is not inserted, but no error occurs. Ignored
errors may generate warnings instead, although duplicate-key errors do
not.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to ‘insert if not exists’ in MySQL?
I have a few inserts and I only want them to actually insert if there isn't already the same information in there.
I only want the insert to run using WHERE NOT EXISTS, would anybody be able to help me adding that to my queries?
Queries:
$db->Query("INSERT INTO `surfed` (site) VALUES('".$id."')");
Thanks so much!
Use the IGNOREkeyword
INSERT IGNORE INTO surfed (user, site) VALUES('".$data['id']."', '".$id."')
If you have a unique key constraint on the user-site combination then it would normally generate an error on duplicates and abort the insertion. Using ignore in the insert statement will ignore the error and just not insert anything.
If you use the IGNORE keyword, errors that occur while executing the INSERT statement are treated as warnings instead. ... With IGNORE, the row still is not inserted, but no error is issued.
See here for more infos about it
SQLFiddle example
You should be able to go with mysql_num_rows. If that returns a value of 0, then there is nothing in your table matching what you want to insert. (WHERE NOT EXISTS).
So make something like "if mysql_num_rows = 0 then insert else do nothing".
First your two columns need to be a combined key, then you can use INSERT IGNORE as outlined by juergen d or use
ON DUPLICATE KEY UPDATE user=user
See similar question here:
INSERT ... ON DUPLICATE KEY (do nothing)
For the revised question of only having a site column, make sure the site column is a unique key or primary key and then use
$db->Query("INSERT INTO `surfed` (site) VALUES('".$id."') ON DUPLICATE KEY UPDATE site=site");
I am trying to prevent duplicates from occuring using the following query, but it doesnt seem to work. Please could you tell me what the problem is?
INSERT IGNORE INTO Following SET `followingUserID` = '$accountIDToFollow', `followerUserID` = '$accountID'
INSERT IGNORE INTO
Following (`followingUserID`,`followerUserID`)
VALUE
('$accountIDToFollow','$accountID')
You were doing an UPDATE format before
If you are trying to do an update this is how it works
UPDATE followingUserID
SET
followingUserID = '$accountIDToFollow',
WHERE
followerUserID = '$accountID';
Of course you want to replace the were clause with the correct condition you want to do
As per MYSQL documentation,
If you use the IGNORE keyword, errors
that occur while executing the INSERT
statement are treated as warnings
instead. For example, without IGNORE,
a row that duplicates an existing
UNIQUE index or PRIMARY KEY value in
the table causes a duplicate-key error
and the statement is aborted. With
IGNORE, the row still is not inserted,
but no error is issued.
It means, the IGNORE does not prevent any record duplicate. You will have to put Unique constraints on your given fields.
I have a PHP foreach loop and a mysql insert statement inside of it. The loop inserts data into my database. I've never ran into this issue before but what I think is happening is that the insert dies (I do not have an "or die" statement after the insert) when it reaches a duplicate record. Even though there may be duplicate records in the table, I need this to just continue. Is there something that I need to specify to do this?
I'm transferring some records from one table to another. Right now, I have 20 records in table #1 and only 17 in table #2. I'm missing 3 records but only one of those are duplicated which violates the constraint on the table. The other two records should have been added. Can someone give me some advice here?
What's happening is that PHP is throwing a warning when the mysql insert fails and stopping on that warning. The best way to accomplish your goal is:
Create a custom exception handler
Set PHP to use the exception handler for warnings.
Wrap the insert attempt into a try / catch
When you catch the exception / warning, either log or output the mysql error but continue script execution.
This will allow your script to continue without stopping while at the same time explaining to you the problem.
One way around this would be to simply query the database for the record that you're about to insert. This way, your series of queries will not die when attempting to insert a duplicate record.
A slightly more efficient solution would be to query for [i]all[/i] of the records you're about to insert in one query, remove all the duplicates, then insert the new ones.
Do you insert multiple rows with one INSERT statement?
INSERT INTO xyz (x,y,z) VALUES
(1,2,3),
(2,3,5),
(3,4,5),
(4,5,6)
Then you might want to consider prepared statements
...or adding the IGNORE keyword to your INSERT statement
INSERT IGNORE INTO xyz (x,y,z) VALUES
(1,2,3),
(2,3,5),
(3,4,5),
(4,5,6)
http://dev.mysql.com/doc/refman/5.0/en/insert.html says:
If you use the IGNORE keyword, errors that occur while executing the INSERT statement are treated as warnings instead
You can still fetch the warnings but the insertion will not be aborted.
Not a good way cause you should figure out whats wrong, but to just prevent it from dieing try adding # in front of the function
#mysql_query = ...
INSERT INTO FOO
(ID, BAR)
VALUES(1,2),(3,4)
ON DUPLICATE KEY UPDATE BAR=VALUES(BAR)