2016-11-04 46 views
0

我有一個生成多個隨機數,並使用以下代碼插入在MySQL數據庫中的相同的應用程序:插入非重複時PHP多個值插入在單個查詢失敗由於複製

FIELDA是主鍵和fieldb是12位隨機密鑰必須是唯一的,並且在數據庫中設置爲唯一。

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

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

其中N(和變量$ N)是行的總數,通常約爲10萬至一百萬對於每次插入表中的

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中檢查我生成的每個代碼,如果它存在於數據庫或生成的新代碼集中。我爲每個實例插入10萬到100萬行的任何地方,這個數據庫只會變得更大。我使用的array_flip,in_array等操作在insert之前搜索重複值時,會使用大數據庫耗盡內存,並導致應用程序崩潰,因此我想避免在PHP中進行重複檢查,而是按照上述方法進行操作。 2)如果上面是可能的,我希望MySQl返回所有成功插入的行,以便我可以輸出這個給用戶。

回答

0

您需要確保在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) { 
}