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

时间:2016-11-04 10:01:58

标签: php mysql database insert duplicates

我有一个生成多个随机数的应用程序,并使用以下代码在MySQL数据库中插入相同的代码:

fielda是主键,fieldb是12位随机密钥,必须是唯一的,并且在DB中设置为唯一。

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

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

其中N(和变量$ N)是总行数,对于表中的每个插入,通常为100,000到100万

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,如果它存在于DB或生成的新代码集中。我在每个实例插入100000到100万行的任何地方,这个数据库只会变大。我用于在插入之前搜索重复值的array_flip,in_array等操作是使用大型数据库耗尽内存并导致应用程序崩溃,因此我想避免在PHP中重复检查,而是如上所述。 / p>

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

1 个答案:

答案 0 :(得分:0)

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

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

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

一旦你有了这个,你会看到失败的插入会抛出PDOException。为了增强稳健性,您应该检查MySQL error code是否为1062

  

错误:1062 SQLSTATE:23000(ER_DUP_ENTRY)

     

消息:密钥%d的重复条目'%s'

     

使用此错误返回的消息使用格式字符串   ER_DUP_ENTRY_WITH_KEY_NAME。

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