【问题标题】:mysqli insert - but only if not a duplicate [duplicate]mysqli 插入 - 但前提是不重复 [重复]
【发布时间】:2013-08-02 03:18:39
【问题描述】:

我是一名 Java 开发人员,刚刚接受了“一些快速简单的 DB 东西”的任务——除了我对 PHP/MySQL 不太了解...我需要将一条记录插入到 DB 中——但只有如果电子邮件字段与数据库中已存在的字段不匹配。以下是我迄今为止收集的 PHP 代码:

// Grab the values from the HTML form:
$newUserName = $_POST['newUserName'];
$newUserName = $mysqli->real_escape_string($newUserName);
$newUserEmail = $_POST['newUserEmail'];
$newUserEmail = $mysqli->real_escape_string($newUserEmail);

// Now search the DB to see if a record with this email already exists:
$mysqli->query("SELECT * FROM RegisteredUsersTable WHERE UserEmail = '$newUserEmail'");

现在我需要查看该搜索是否有任何返回 - 这意味着电子邮件已经存在 - 如果是,我需要提醒用户,否则我可以继续使用以下方法将新信息插入数据库:

$mysqli->query("INSERT INTO RegisteredUsersTable (UserName, UserEmail) VALUES ('".$newUserName."', '".$newUserEmail."')");

有什么想法吗?

【问题讨论】:

  • 在数据库上设置unique 约束。然后最后从$mysqli->error读取,如果有错误,那就是重复了。
  • 你到底在问什么?您想要更好的查询方式吗?还是您要求一些 PHP 代码将它们粘合在一起?
  • @MikeW:我相信他想在用户表中插入一些数据,而不是插入重复的数据(例如同一电子邮件的两行)。
  • 对。我认为我到目前为止的代码还可以(也许不是最好的,但还可以) - 所以我只是缺少将它们粘合在一起的 if 语句的代码。
  • 我的第一条评论有用吗?如果您决定对数据库进行验证,那么您只需访问数据库一次(使用 PHP)。

标签: php mysql search insert mysqli


【解决方案1】:

根据您的代码工作,这应该会为您指明正确的方向。也许有更好的方法来构建您的数据库,从而更好地利用它。

<?php

$mysqli = new mysqli("localhost", "iodine", "iodine","iodine");

// Grab the values from the HTML form:
/*
$newUserName = $_POST['newUserName'];
$newUserName = $mysqli->real_escape_string($newUserName);
$newUserEmail = $_POST['newUserEmail'];
$newUserEmail = $mysqli->real_escape_string($newUserEmail);
*/
$newUserName = "Test User";
$newUserEmail = "test4@example.com";

// Now search the DB to see if a record with this email already exists:
echo "SELECT * FROM RegisteredUsersTable WHERE UserEmail = '$newUserEmail'", "\n";
$result = $mysqli->query("SELECT * FROM RegisteredUsersTable WHERE UserEmail = '$newUserEmail'");

if (!$result) {
  die($mysqli->error);
}
echo "num_rows = ".$result->num_rows."\n";
if ($result->num_rows > 0) {
   echo "Duplicate email\n";
   // do something to alert user about non-unique email
} else {
  $result = $mysqli->query("INSERT IGNORE INTO RegisteredUsersTable (UserName, UserEmail) VALUES ('".$newUserName."', '".$newUserEmail."')");
  if ($result === false) {echo "SQL error:".$mysqli->error;}
}

?>

【讨论】:

  • 如果我使用此代码,是否还需要按照@hellohellosharp 发布的答案先ALTER IGNORE 表?
  • 否 - 这是基于您的原始结构,只是为了给您一些 PHP 胶水。 @hellohellosharp 已经解决了由数据库上的两个查询引起的可能的竞争条件 - 他的数据结构更好,但是您使用的 PHP 会有所不同,只需执行一个查询。
  • 好的,我想我必须尝试这两种方法,看看哪个更好?对于它的价值,我不希望这个数据库有那么大。也许像 10k 用户一样 - 我还应该担心比赛和性能问题吗?
  • 我的一般方法是在问题发生之前将其编码出来,所以是的,你应该担心。实际上,除非有人恶意,否则您不太可能遇到问题。
  • 它不工作。我实现了您建议的代码,但此后已经成功插入了 3 次具有完全相同电子邮件的条目...注意到die($mysqli-&gt;error; 行上缺少“)”-您发布的代码中是否还有其他可能的拼写错误/遗漏机会?
【解决方案2】:

考虑在这个特定的表上放置一个unique 索引。以下代码将添加索引并删除所有当前重复项:

ALTER IGNORE TABLE `RegisteredUsersTable` ADD UNIQUE INDEX unique_email (`UserEmail`);

添加后,使用INSERT IGNOREINSERT...ON DUPLICATE KEY UPDATE。他们只会在没有重复的情况下执行插入。

$mysqli->query("INSERT IGNORE INTO RegisteredUsersTable (UserName, UserEmail) VALUES ('".$newUserName."', '".$newUserEmail."')");

Mysql 会抛出错误,因为电子邮件已经在数据库中。但是,IGNORE 命令告诉脚本不要注意此查询的错误,因为在这种情况下,您希望它用于重复行。

此外,即使使用INSERT IGNORE,也可以通过失败或成功消息提醒用户。使用 MYSQLLAST_INSERT_ID()。如果给出了 ID,则将其插入。如果不是,那么电子邮件已经存在(或有另一个错误)。

【讨论】:

  • +1,正如我所说,您还可以提到,这种方法比手动检查另一个查询更好,原因有两个。 1.不是racy,2.只命中数据库一次。
  • @DaveChen - 我同意,并且我个人总是使用 INSERT...ON DUPLICATE KEY UPDATE。 INSERT IGNORE 更容易理解,这就是我使用它作为示例的原因。 OP 应该研究两者并做出自己的决定。
  • @hellohellosharp - 这看起来不错,但 Mike W 给出的答案也是如此 - 那么我应该如何决定呢? :-) 我想将您的两个答案都标记为正确(这当然是不可能的),但我需要先尝试实施它们......该怎么办?
【解决方案3】:

对于您的第一个查询,为了减轻服务器上的负载,请改用 count()。

$mysqli->query("SELECT count(*) FROM RegisteredUsersTable WHERE UserEmail = '$newUserEmail'");

这样,你可以只检查你得到的结果是否大于 1。如果结果大于 1,则用户名存在(因为返回了一行)。

要检查返回的数据,您只需执行语句,然后获取结果。部分乐趣在于学习,这里是documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-02
    • 2019-06-20
    • 1970-01-01
    • 2016-01-20
    • 2013-05-26
    • 2014-12-04
    相关资源
    最近更新 更多