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

Tho*_*son 6 php mysql

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

EG我将如何解决这个问题:

$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());
  }
}
Run Code Online (Sandbox Code Playgroud)

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

我无法使用,ON DUPLICATE KEY UPDATE因为我想使用最后插入的id更新不同的表,或者无法复制的记录的id.

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

谢谢

Álv*_*lez 6

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

  • duplicate在错误消息的文本中查找子字符串看起来不是很健壮.您可以针对重复条目的代码测试mysql_errno()的值,即1062(您可以在手册中找到所有代码).
  • 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');
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 或者,只需运行上一个查询(没有理由避免它):

    SELECT id
    FROM table
    WHERE col1=... AND col2=...
    FOR UPDATE
    
    Run Code Online (Sandbox Code Playgroud)

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