【问题标题】:Check for duplicates before inserting插入前检查重复项
【发布时间】:2011-12-04 20:45:07
【问题描述】:

在插入数据库之前,我使用以下代码检查重复项。对我来说,只有当 namedescriptionpricecityenddate 匹配时,才会认为重复。

foreach($states_to_add as $item) {
    $dupesql = "SELECT 
                    COUNT(*) 
                FROM 
                    table 
                WHERE 
                    (   
                        name = '$name' 
                        AND description = '$description' 
                        AND manufacturer = '$manufacturer' 
                        AND city ='$city' 
                        AND price = '$price' 
                        AND enddate = '$end_date'
                    )";

    $duperaw = mysql_query($dupesql);

    if($duperaw > 0) {
        echo nl2br("$name already exists in $city \n");
    } 
    else {
        $sql = "INSERT INTO table (..... (here go the values to be inserted)
        ....

每个值都是在运行此检查之前定义的,我的结果总是在项目已经存在时返回。我转储了“dupesql”并将命令复制/粘贴到 phpmyadmin 中,返回计数为 0。

【问题讨论】:

  • 在您的 SELECT 和您的 INSERT 之间可能会发生来自其他地方的 INSERT,然后您的数据就会损坏。不要自己做唯一性检查,在数据库中添加一个唯一约束并忽略预期的“唯一约束违规”错误。

标签: php mysql duplicates


【解决方案1】:

您想要执行以下操作:

$dupesql = "SELECT * FROM table where (name = '$name' AND description = '$description' AND manufacturer = '$manufacturer' AND city ='$city' AND price = '$price' AND enddate = '$end_date')";

$duperaw = mysql_query($dupesql);

if (mysql_num_rows($duperaw) > 0) {
  //your code ...
}

更多信息请参见Here

【讨论】:

  • 你打错字了先生.. if (mysql_num_rows($duberaw) > 0) {
【解决方案2】:

在我看来,您的问题可以分为两部分。为什么我的 PHP 代码不起作用?我不知道,不太了解PHP,其他人似乎刚刚回答了这个问题:-)。第二个问题是如何检查重复项?您正在以完全错误的方式检查重复项。

在你的桌子上创建一个unique index / primary key。然后,当您尝试插入数据库时​​,如果存在重复,则会引发错误。捕获错误并按照您的意愿处理它。计算记录的数量绝对是错误的方法,并且会严重影响您的代码速度。

【讨论】:

  • 当我推进这个项目并填写更多数据时,我正在阅读此内容,我还不是 100% 确定(还)如何指定唯一索引/主键基于我描述的所有值(名称、描述、价格、城市、结束日期)。
  • @Mike,我提供了 MySQL 官方网站的链接,应该会给你一些帮助。考虑一下并查看您实际上不需要让 PHP 代码工作的答案。如果您尝试插入并捕获异常,那么其余代码不需要在那里......
  • 谢谢!我正在阅读。不过目前,使用 if count > 0 似乎可行。我担心未来的扩展以及在添加更多过滤器进行检查时必须更改主键的参数。
【解决方案3】:

您仍然可能遇到竞争条件,即 2 个用户尝试同时插入重复数据,同时使用 select 语句检查重复数据可以让两个用户继续插入他们的记录。我更喜欢在数据库上设置唯一索引,然后捕获从数据库中冒出的错误。

【讨论】:

  • 它不是多个用户将信息添加到数据库中,而是一个人每天解析一次或两次新提要。出于这个原因,性能并不是一个大问题。
【解决方案4】:

你不需要在 PHP 中检查唯一性,你可以在 MySQL 中做整个测试:

INSERT INTO table1 (name, description, ......)
  SELECT name1, description1, manufacturer1, city1, price1, enddate1
  FROM (SELECT * FROM ( 
    SELECT 
      @name:= '$name' as name1
      ,@description:= '$description' as description1
      ,.....
    FROM DUAL as d1
    LEFT JOIN table1 t1 
           ON (t1.name = d1.name1 
          AND t1.description = d1.description1
          AND ......)
    WHERE t1.name IS NULL) s1) s2

这只会插入通过唯一性测试的值。

【讨论】:

  • 我在每个值上插入了大约 20-30 个值,从我现在的角度来看,这可能会变得相当混乱,尽管我很可能是错的。
【解决方案5】:

试试这个:

foreach($states_to_add as $item) {
    $dupesql = "SELECT 
                    name 
                FROM 
                    table 
                WHERE 
                    (name = '$name' 
                        AND description = '$description' 
                        AND manufacturer = '$manufacturer' 
                        AND city ='$city'
                        AND price = '$price' 
                        AND enddate = '$end_date'
                    )";

    $duperaw = mysql_query($dupesql);

    if( mysql_num_rows($duperaw) ) {
        echo nl2br("$name already exists in $city \n");
    } 
    else {
        $sql = "INSERT INTO table (..... (here go the values to be inserted)

【讨论】:

  • 如果你离开 COUNT(*) 总是会有一行,所以问题还没有解决。
  • 你说得对,我忘了把COUNT(*)改成name或者*
【解决方案6】:

简而言之,您需要通过 PHP 进行检查,并且您还需要在 MySQL 表中添加复合唯一约束以获得两全其美。

如果我们将您的问题分成两个单独的问题会很好。

1- 如何使用 PHP 检查重复项并在执行查询之前通知用户? 2- 如何在 MySQL 中指定复合唯一约束?

首先,您需要一个简单的 PHP 函数来检查数据库中是否存在这条记录,如下所示:

function is_exist($table, $data){
    $sql = "SELECT * FROM `" . $table . "` WHERE ";

    foreach ($data as $key => $val) :
    $sql .= "`$key`='" . $val . "' AND ";
    endforeach;

    $sql = substr($sql,0, -5);

    $result = $mysql_query($sql);
    $count = $mysql_num_rows($result);

    return ($count > 0) ? true: false;
}   

你应该像下面这样调用你的 PHP 函数:

    $data = array('column1'=>$_POST['value'],'column2'=>$_POST['value'], ...);

    if(is_exist($data)){
      // Print your error message
    }else{
     // Run your insert query
    }

这样你可以在去MySql数据库之前防止重复,但是为了有一个重复的免费数据库,你需要在你的MySQL表中添加一个复合唯一约束。

这个简单的 SQL 命令可以解决问题:

alter table `tablename` add unique index(name, description, manufacturer, city, price, enddate);

希望对你有帮助,如果我搞砸了,请给我负担。

【讨论】:

    【解决方案7】:

    尝试关注

      INSERT IGNORE INTO person_tbl (last_name, first_name) 
      -> VALUES( 'Jay', 'Thomas');
    

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 2021-01-20
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      相关资源
      最近更新 更多