【问题标题】:PHP / MySQLi - Catch unique ID conflictPHP / MySQLi - 捕获唯一 ID 冲突
【发布时间】:2014-08-10 00:26:16
【问题描述】:

我想知道在执行 INSERT 时是否有一种简单的方法可以检查 INSERT 语句是否由于 MySQL 字段上的唯一索引而触发冲突。

例如,假设我正在向数据库添加用户,而username 是唯一索引:

$sql = new MySQLi(...);
$res = $sql->query('INSERT INTO `users` (`username`) VALUES ("john_galt");');

名为 john_galt 的用户已经存在,因此不会执行 INSERT。但是我怎样才能最好地用有意义的错误来响应用户(即具有该用户名的用户已经存在;请选择一个唯一的名称。)?

我想到了几件事,例如检查是否设置了 insert_id —— 如果查询产生错误,则不应该设置。但那个错误可能是任何东西

同样,我可以检查$sql->error 是否不为空,但同样,它也可能是任何东西——语法错误,或格式错误的值,或其他任何东西。显然我不会为最终用户打印出实际的 MySQL 错误。

我能想到的两个解决方案是:

  • 在运行 INSERT 之前,运行 SELECT TRUE FROM ``users`` WHERE ``username`` = "john_galt"; 以查看用户名是否已存在于数据库中,但我觉得我在字段中添加了一个唯一的约束,这样我就不必这样做了——有点失败其他目的。
  • strpos($sql->error, 'Duplicate entry') === 0 -- 看起来非常骇人。

有没有更好的方法来使用 PHP 的 MySQLi 类来确定这一点?

【问题讨论】:

  • 我建议在尝试INSERT 之前先进行验证。比预期的失败节省更多时间。 :)
  • 好吧,这不会是一个意外的失败......如果我必须在插入另一行之前手动检查它的存在,那么拥有一个唯一字段(即除了主索引之外)有什么意义?
  • 我同意这是拥有唯一字段的关键,提前检查没有内在价值。在大多数情况下,有效插入比冲突更常见,因此简单地执行插入并响应错误条件会更有效。

标签: php mysql mysqli unique-constraint


【解决方案1】:

您可以使用errno 获取返回的错误代码并使用它,例如:

if($sql->errno === 1062) {
    //do something
}

这里是 MySQL 5.5 的错误代码列表:http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html

【讨论】:

  • 谢谢!我从来没有想到这一点!如果 PHP 的 MySQLi 类在某个地方包含这些常量,那就太酷了,这样我就没有使用文字错误代码。
  • 不是我可能需要得到那个具体的,但是否也可以提取字段的名称,以防有多个字段具有唯一约束并且错误消息应该是更具体?
  • @MMiller 除了使用某种正则表达式从返回的错误字符串中提取字段名称之外,我不知道有任何方法可以做到这一点。使用这种方法的问题是,我认为即使有多个重复的唯一字段,MySQL 也只会为它遇到的第一个返回错误。顺便说一句,如果您需要同时使用错误字符串和错误代码,请查看error_list,它将所有这些信息返回到一个数组中。
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2020-05-16
  • 1970-01-01
  • 2022-09-23
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多