Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get ID of record when mysql returns duplicate error

Tags:

php

mysql

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

like image 891
Thomas Clayson Avatar asked Feb 01 '12 10:02

Thomas Clayson


People also ask

How do I fetch duplicate records from a table in SQL?

One way to find duplicate records from the table is the GROUP BY statement. The GROUP BY statement in SQL is used to arrange identical data into groups with the help of some functions. i.e if a particular column has the same values in different rows then it will arrange these rows in a group.

How do I count repeating values in MySQL?

Find Duplicate Row values in One ColumnSELECT col, COUNT(col) FROM table_name GROUP BY col HAVING COUNT(col) > 1; In the above query, we do a GROUP BY for the column for which we want to check duplicates. We also use a COUNT() and HAVING clause to get the row counts for each group.


1 Answers

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).

like image 178
Álvaro González Avatar answered Oct 01 '22 01:10

Álvaro González