php - 当 PHP 在单个查询中插入多个值由于重复而失败时插入非重复项

标签 php mysql database insert duplicates

我有一个应用程序,可以生成多个随机数并使用以下代码将其插入到 MySQL 数据库中:

fielda 是主键,fieldb 是 12 位随机键,要求必须唯一,并在数据库中设置为唯一。

$datafields = array('fielda', 'fieldb', 'created_on');

$data = array(value1a, value1b, 'now()',value2a, value2b, 'now()' ....valueNa, valueNb, 'now()');

其中 N(和变量 $N)是总行数,表中每次插入的行数通常约为 100,000 到一百万

function placeholders($text, $count=0, $separator=","){
    $result = array();
    if($count > 0){
        for($x=0; $x<$count; $x++){
            $result[] = $text;
        }
    }

    return implode($separator, $result);
}
$pdo->beginTransaction(); // also helps speed up your inserts.
for($i=0;$i<$N;$i++){
    $question_marks[] = '('  . placeholders('?', 7) . ')';

}

$sql = "INSERT INTO code (" . implode(",", $datafields ) . ") VALUES " . implode(',', $question_marks);
$stmt = $this->db->prepare($sql);
try {
    $stmt->execute($data);
} catch (PDOException $e){
    echo $e->getMessage();
}
$pdo->commit();

我对上述内容有以下疑问:

就我而言,我一次插入接近 100000 行。如果我理解正确并形成了我运行的实验,即使查询中的一行有 fieldb 或 fielda 的重复项,整个查询也会失败。

1) 是否可以更改此行为并至少插入那些不重复的行,并返回行数和找到重复项的字段值,以便仅重新生成这些行。我想这样做是为了避免在 PHP 中检查我生成的每个代码(如果它存在于数据库中)或生成的新代码集。我在每个实例中插入 100000 到 100 万行,并且这个数据库只会变得更大。我用来在插入之前搜索重复值的 array_flip、in_array 等操作在大数据库中耗尽内存并导致应用程序崩溃,因此我想避免 PHP 中的重复检查,而是按照上面的方法执行。

2)如果上述情况可行,我希望 MySQl 返回所有成功插入的行,以便我可以将其输出给用户。

最佳答案

您需要确保插入在 MySQL 级别失败。为此,您必须使随机数属于唯一索引,例如:

CREATE TABLE code (
    -- [...]
    UNIQUE INDEX fieldb_unique (fieldb)
);

这具有确保数据完整性的额外好处。

一旦获得此信息,您将看到失败的插入将抛出 PDOException。为了增加稳健性,您应该检查 MySQL error code 是否是1062:

Error: 1062 SQLSTATE: 23000 (ER_DUP_ENTRY)

Message: Duplicate entry '%s' for key %d

The message returned with this error uses the format string for ER_DUP_ENTRY_WITH_KEY_NAME.

list($sqlstate, $mysql_code, $message) = $stmt->errorInfo();
if ($mysql_code==1062) {
}

关于php - 当 PHP 在单个查询中插入多个值由于重复而失败时插入非重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40419824/

相关文章:

android - 创建表时出错

php - 如何在数据库中存储轻量级格式(Textile、Markdown)?

php - Symfony2 获取位于 security.yml 中的 access_control 参数

ruby-on-rails - 如何在 Rails 4 中正确设置 database.yml 文件

php - 删除多个复选框上的行后未获取 $_GET 的值?

mysql - SQL 通过 null 连接查找缺失记录

sql-server - 自动将新数据从 MS Access 数据库导入 SQL Server

php - iPhone SDK 付款后,我的 php IPN 回调中缺少 POST 参数

php - 限制对 PHP 管理按钮的访问

php - 将数组元素插入数据库