update record if exists, else write new record? - php

I'm trying to execute this query and when it finds a record for $serial, it can update it. OR, if the serial doesn't exist, it can write a new record.
I get syntax erros but to me it seems fine. pretty darn sure ON DUPLICATE KEY UPDATE is the way to go but i'm missing something...
$query = "INSERT INTO `".$sys_id."` (serial, status) VALUES ('98745', 'active') ON DUPLICATE KEY UPDATE";
$result = mysql_query($query) or die(mysql_error());

you need to tell it what to update (see manual)
so:
$query = "INSERT INTO `".$sys_id."` (serial, status) VALUES ('98745', 'active')
ON DUPLICATE KEY UPDATE status=VALUES(active)";
(i am under the assumption that the key is serial)

Related

MySQL DELETE failing randomly and very infrequently

I have a MySQL DELETE statement followed by an INSERT statement to ensure only one copy of a data set for a given ID. (There is a reason why I do not use UPDATE)
The problem is that I have noticed in a data set spanning 5000+ entries that there are 3 instances where the DELETE statement did not execute, but the INSERT statement did. The end result was duplicate entries for the given IDs.
Below is my code. On execution failure the php script will exit with an error message. It must be my level of experience. Any ideas what the problem could be?
//delete
$query_delete = "DELETE FROM q1_6_list WHERE q_id = '".mysql_real_escape_string($q[qID])."'";
$result = mysql_query($query_delete) or errorReport("Error in query: $query_delete. ".mysql_error());
//insert
$query_insert = "INSERT INTO q1_6_list (q_id, vehicle, quantity) VALUES";
$result = mysql_query($query_insert) or errorReport("Error in query: $query_insert. ".mysql_error());
if (!$result)
errorReport($result);
EDIT
On closer inspection I noticed that I did not add the below code right after $result = mysql_query($query_delete)....
if (!$result)
errorReport($result);
Could this also be required to catch all other error messages, or would mysql_query($query_delete) or errorReport... catch all error occurrences?
Your best bet here is to create a primary key on q1_6_list (q_id):
ALTER TABLE q1_6_list ADD PRIMARY KEY(q_id)
and use MySQLs REPLACE INTO syntax, so lose your delete and your insert becomes:
$query_insert = "REPLACE INTO q1_6_list (q_id, vehicle, quantity) VALUES";
You could simply run insert query only if delete query was successful:
if (mysql_query($query_delete)) {
mysql_query($query_insert);
}

Syntax error with IF EXISTS UPDATE ELSE INSERT

I'm using MySQL 5.1 hosted at my ISP. This is my query
mysql_query("
IF EXISTS(SELECT * FROM licensing_active WHERE title_1='$title_1') THEN
BEGIN
UPDATE licensing_active SET time='$time' WHERE title_1='$title_1')
END ELSE BEGIN
INSERT INTO licensing_active(title_1) VALUES('$title_1')
END
") or die(mysql_error());
The error is
... check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS(SELECT * FROM licensing_active WHERE title_1='Title1') THEN ' at line 1
My actual task involves
WHERE title_1='$title_1' AND title_2='$title_2' AND version='$version' ...ETC...
but I have reduced it down to make things simpler for my problem solving
In my searches on this, I keep seeing references to 'ON DUPLICATE KEY UPDATE', but don't know what to do with that.
Here is a simple and easy solution, try it.
$result = mysql_query("SELECT * FROM licensing_active WHERE title_1 ='$title_1' ");
if( mysql_num_rows($result) > 0) {
mysql_query("UPDATE licensing_active SET time = '$time' WHERE title_1 = '$title_1' ");
}
else
{
mysql_query("INSERT INTO licensing_active (title_1) VALUES ('$title_1') ");
}
Note: Though this question is from 2012, keep in mind that mysql_* functions are no longer available since PHP 7.
This should do the trick for you:
insert into
licensing_active (title_1, time)
VALUES('$title_1', '$time')
on duplicate key
update set time='$time'
This is assuming that title_1 is a unique column (enforced by the database) in your table.
The way that insert... on duplicate works is it tries to insert a new row first, but if the insert is rejected because a key stops it, it will allow you to update certain fields instead.
The syntax of your query is wrong. Checkout http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html
Use the on duplicate key syntax to achieve the result you want. See http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
Another solution
$insertQuery = "INSERT INTO licensing_active (title_1) VALUES ('$title_1')";
if(!$link->query($insertQuery)){ // Insert fails, so update
$updateQuery = "UPDATE licensing_active SET time='$time' WHERE title_1='$title_1'";
$link->query($updateQuery);
}
Here is the example I tried and its works fine:
INSERT INTO user(id, name, address) VALUES(2, "Fadl", "essttt") ON DUPLICATE KEY UPDATE name = "kahn ajab", address = "Address is test"
I am amazed to see so many useless codes and answers...
Just replace INSERT with REPLACE.
¯\(ツ)/¯

How to get the id of the duplicated entry?

$query = "INSERT IGNORE INTO `user` (`name`, `email`) VALUES ( '".$name."', '".$email."')";
$res = mysql_query($query) or die("Query failed ".mysql_error() );
$last id = mysql_insert_id();
mysql_insert_id() return 0 if there is a duplicated entry.
Is there a way to get the ID of the duplicated entry ? or do I have to do 2 query ( SELECT + INSERT ) ?
There is no way with an INSERT to get the ID of the existing (duplicate) entry.
Still, you should not do a SELECT + INSERT because you would need to lock the table for concurrency (to ensure that nothing has changed between SELECT and INSERT).
In this case, if the insert fails, and you want to update the existing record instead, use INSERT ... ON DUPLICATE KEY UPDATE.
If you just want to fail, but have the existing ID, then fail, and do a SELECT to get the existing entry.

Get ID of record when mysql returns duplicate error

Is there a way to retrieve the ID of a record (primary key) after an insert when the mysql error returns a duplicate key?
E.G. How I would go about it:
$sql = "INSERT INTO table (`col1`, `col2`) VALUES ('$val1', '$val2')";
$result = mysql_query($sql);
if($result){
$id = mysql_insert_id();
}
else {
if(stristr(mysql_error(), "duplicate"){
$sql = "SELECT `id` FROM `table` WHERE `col1`='$val1' AND `col2`='$val2'";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$id = $row['id'];
}
else {
die(mysql_error());
}
}
Here I've had to do two sql statements which not only take time and effort, but duplicate code as well.
I cannot use ON DUPLICATE KEY UPDATE because I want to update a different table using the either the last inserted id, or the id of the record that cannot be duplicated.
So, am I right in what I'm doing? Or is there a way to get the id of the row?
Thanks
MySQL will not tell you which record holds the original value, you'll have to find out yourself. Here you are some tips:
Looking for the duplicate substring in the text of the error message does not look very robust. You can just test the value of mysql_errno() against the code for duplicate entry, which is 1062 (you can find all codes in the manual).
The mysql extension does not provide a mechanism to find out name of the violated key, so you'll have to use the non-robust approach of parsing the text of the error message:
if( preg_match("/Duplicate entry '.*' for key '(.*)'/Ui", mysql_error(), $matches) ){
$violated_key = $matches[1];
}else{
throw new Exception('Could not find violated key name');
}
Alternatively, just run a previous query (there's no reason to avoid it):
SELECT id
FROM table
WHERE col1=... AND col2=...
FOR UPDATE
The FOR UPDATE clause will lock matching rows to avoid race conditions (assuming InnoDB).

Check if exists, if so, update by 1++, if not insert

Hey guys quick question, I currently have an insert statement
$query= "INSERT into new_mail VALUES ('$to1', '0')"; where fields are username, and message_number
Currently what I would do to check if the entry exists, is do a select query then check the number of rows with mysql_num_rows (php). If rows==1 then I get the current message_number and set it equal to
$row['message_number']+1.
Then I update that entry with another query.
Is there an easier way to do all this in just mysql with just one query (check if exists, if not insert, if so update message_number, increase by 1)?
Depending on how your table is structured, you may be able to use the ON DUPLICATE KEY UPDATE (link to the MySQL manual) feature of INSERT:
INSERT into new_mail VALUES ('$to1', '0') ON DUPLICATE KEY UPDATE message_number=message_number+1
Use INSERT...ON DUPLICATE KEY UPDATE. The MySQL manual has an example which does almost exactly what you need:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
To make this work you need to add a UNIQUE index on the column that you use to check for duplicates. There is one important warning though:
In general, you should try to avoid using an ON DUPLICATE KEY clause on tables with multiple unique indexes.
Got a little confused by your question and your table structures but I think you want something like this.
INSERT INTO new_mail (username, message_number)
VALUES ($username, $message_number)
ON DUPLICATE KEY UPDATE message_number=message_number + 1;
This is presuming username is your primary key (more likely something like userid). Hope this helps.
EDIT: The ON DUPLICATE KEY UPDATE answers are better, but you could do this (eludes the select query):
Assuming you're using the mysqli extenson:
$db = //Some construction of mysqli object;
$sql = 'UPDATE tablename SET RowValue = RowValue + 1 WHERE message_number = ?';
$updateStatement = $db->prepare($sql);
$updateStatement->bind_param('i', $message_number);
$message_number = //Set message number;
$updateStatement->execute();
if ($updateStatement->affectedRows == 0) {
$sql = 'INSERT INTO tablename (RowValue, message_number) VALUES (?, ?)';
$insertStatement = $db->prepare($sql);
$insertStatement->bind_param('ii', $rowValue, $messageNumber);
$rowValue = something;
$messageNumber = something;
$insertStatement->execute();
}

Categories