当mysql返回重复错误时获取记录的ID

时间:2012-02-01 10:54:28

标签: php mysql

当mysql错误返回重复键时,有没有办法在插入后检索记录(主键)的ID?

E.G。我该怎么做:

$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());
  }
}

在这里,我不得不做两个sql语句,不仅需要花费时间和精力,还需要重复代码。

我无法使用ON DUPLICATE KEY UPDATE,因为我想使用最后插入的ID或无法复制的记录的ID更新其他表。

那么,我正在做我正在做的事情吗?或者有没有办法获得行的ID?

由于

1 个答案:

答案 0 :(得分:6)

MySQL不会告诉你哪条记录保留了原始值,你必须自己找出来。这里有一些提示:

  • 在错误消息的文本中查找duplicate子字符串看起来不太健壮。您只需针对重复条目的代码测试mysql_errno()的值,即1062you can find all codes in the manual)。
  • mysql扩展不提供查找被违反密钥名称的机制,因此您必须使用非健壮的方法来解析错误消息的文本:

    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');
    }
    
  • 或者,只需运行上一个查询(没有理由避免它):

    SELECT id
    FROM table
    WHERE col1=... AND col2=...
    FOR UPDATE
    

    FOR UPDATE子句将锁定匹配的行以避免竞争条件(假设InnoDB)。