php - MySQL 表中的 PDO 'ON DUPLICATE KEY UPDATE' rowCount() 返回双倍数量的更新记录

标签 php mysql pdo

我正在处理一个上传 CSV 并更新 MySQL 表的项目。 在我的 sql 插入语句的末尾,我有一个“重复键更新...”语句。

我的问题是,PDO rowCount() 似乎为更新的行返回 2x。 例如,当我第一次上传 CSV 时,我总共得到 100 行(csv 行的计数)并且 rowCount 返回 100,这是有道理的,因为我插入了 100 行。

但是,如果我再次上传同一个文件,所有 100 行都会更新(我更新了一个 unix 时间戳),并且 rowCount 返回 200。我认为这是因为 rowCount 每次更新都返回 2,而插入则返回 1。

我的假设是否正确?有没有人遇到过这个问题,有没有不涉及 100 个单独的插入语句的解决方案?我希望能够显示 csv 中的总行数、插入的新行总数和更新的总行数。

$sql = 'INSERT INTO projects (' . implode($fields,',') . ') VALUES';
    $rowCount = count($csvData);
    $tmp = array();
    for( $i = 0; $i < $rowCount; $i++ ){
        $placeholders = array();
        foreach( $fields as $key=>$val ){

            /* do some post processing for special characters */
            switch($val){
                case 'description':
                    $value = !empty($csvData[$i][$_POST[$val]]) ? $csvData[$i][$_POST[$val]] : NULL;
                    array_push($tmp,$value);
                break;
                case 'country':
                    $value = !empty( $csvData[$i][$_POST[$val]] ) ?  implode(' ',array_unique(explode(' ', $csvData[$i][$_POST[$val]]))) : NULL;
                    $value = str_replace(array(',','.','\''),'',$value);
                    array_push($tmp,$value);
                break;
                case 'add_unixtime':
                    array_push($tmp,time());
                break;
                case 'project_type':
                    array_push($tmp,strtolower($formData['project_type']));
                break;
                default:
                    $value = !empty($csvData[$i][$_POST[$val]]) ? str_replace(array(',','.','\''),'',$csvData[$i][$_POST[$val]]) : NULL;
                    array_push($tmp,$value);
                break;
            }
            array_push($placeholders,'?');
        }
        $sql .= ' (' . implode($placeholders,',') . '),';
    }
    /*  
        detect duplicate projects based on project_number & project_type
        mysql unique index created with (project_number + project_type)
        if duplicate found, update row
    */
    $sql = rtrim($sql,',');
    $sql .= 'ON DUPLICATE KEY UPDATE';
    foreach($fields as $key=>$val){
        $sql .= ' ' . $val . ' = VALUES(' . $val . '),';
    }
    $sql = rtrim($sql,',');

    /* update database */
    $query = $this->dbc->prepare($sql);
    if( $query->execute($tmp) ){
        $result = array('total_rows'=>$rowCount,'modified_rows'=>$query->rowCount());
    }

    /* return result */
    return $result;

这是为 3 行插入生成的查询。

INSERT INTO projects (project_number, project_value, project_name, 
    address1, address2, city, state, zip, country, description,  
    project_type, add_unixtime ) 
VALUES (?,?,?,?,?,?,?,?,?,?,?,?), 
        (?,?,?,?,?,?,?,?,?,?,?,?), 
        (?,?,?,?,?,?,?,?,?,?,?,?)  
    ON DUPLICATE KEY UPDATE 
        project_number = VALUES(project_number), 
        project_value = VALUES(project_value), 
        project_name = VALUES(project_name), 
        address1 = VALUES(address1), address2 = VALUES(address2), 
        city = VALUES(city), state = VALUES(state), zip = VALUES(zip), 
        country = VALUES(country), description = VALUES(description), 
        project_type = VALUES(project_type), 
        add_unixtime = VALUES(add_unixtime); 

最佳答案

根据MySQL手册:

对于 ON DUPLICATE KEY UPDATE,如果该行作为新行插入,则每行的受影响行值为 1,如果更新现有行,则为 2,如果现有行设置为其当前值,则为 0。

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

关于php - MySQL 表中的 PDO 'ON DUPLICATE KEY UPDATE' rowCount() 返回双倍数量的更新记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14611680/

相关文章:

php - 如何使用 php 转义字符串中的单引号(撇号)

php - 我怎样才能使用php中的prepare语句获取insert_id?

php接口(interface)方法覆盖

javascript - 防止在表单提交后重定向到 php 文件

mysql - 如何执行.sql文件创建新表

php - 循环通过 MySQL 左加入 php 与 2 个单独的查询

php - Left Join获取上一条记录sql

php - Yii:在新窗口中打开网址,而不是在新选项卡中

php - 在 MYSQL 中重新格式化日期以在 PHP 中输​​出

PHP/PDO - 刷新权限