2013-07-31 27 views
0

讓我們想象一下,我們應該使用PDO在循環中插入很多行。PHP PDO - 不會在循環中插入所有語句

$sql = "INSERT INTO products (name, price) VALUES (:name, :price)"; 
$stmt = $db->prepare($sql); 

for ($i = 0; $i < 100; $i++) 
{ 
    $name = md5(rand(0, 1000)); 
    $price = rand(0, 1000); 

    $stmt->bindParam(':name', $name); 
    $stmt->bindParam(':price', $price); 

    try 
    { 
     $result = $stmt->execute(); 

     if (!$result) 
     { 

      print_r($db->errorInfo()); 
     } 

     echo $db->lastInsertId(); 
    } 
    catch (Exception $e) 
    { 
     echo $e->getMessage(); 
    } 
} 

這樣所有100行都不會被插入到數據庫中。和回聲,在23日線將輸出類似:

1 2 3 4 5 ... 59 60 61 61 61 61 61 61

和print_r的在20日線將輸出

Array (
    [0] => 00000 
    [1] => 
    [2] => 
) 

PDO錯誤代碼00000意味着一切正常。沒有行受到影響。如果我嘗試手動插入$ result爲false的行 - 一切正常。

只有61行將被插入表中。而且每次腳本運行這個數字都在變化,這是真的很奇怪

爲什麼?

以其他方式 - 我們可以從所有插入查詢中做出一個查詢,並且將會插入所有100行。這是一個link到代碼的pastebin。

這裏是一個表結構:

CREATE TABLE IF NOT EXISTS `products` (
`id` int(10) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `price` int(10) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

順便說一句。我使用percona MySQL服務器(5.5)與HandlerSocker插件。 我嘗試使用HandlerSocket插入行。這裏是一個代碼

$hs = new \HSPHP\WriteSocket(); 
$hs->connect(); 

$id = $hs->getIndexId('test','products','','name,price'); 
$loops_number = 10000; 

for ($i = 0; $i < $loops_number; $i++) 
{ 
    $name = 'handler-'.md5(rand(0, 1000)); 
    $price = rand(0, 1000); 

    $hs->insert($id, array($name, $price)); 
} 

而我之後 - 我有〜14000行在DB。爲什麼?另外,如果我改變的循環數(可變$ loops_number) -

if 10 loops - I have 100 rows in DB table 
if 50 loops - 50 rows 
if 100 loops - 100 rows 
if 500 loops - 500 rows 
if 1000 loops - ~1100 rows and this number always change. (if I truncate table and run script again) 

似乎問題,我的MySQL服務器?

+0

可能有許多重複61的原因。這將有助於發佈您的實際代碼。這不是,對嗎? – Galen

+2

您只需在循環前準備一次該語句。無需準備100次:) –

+1

你的意思是它總是停留在61? – dbf

回答

0

我通過重新安裝PHP來解決此問題。 (我用PHP從這個回購:ppa:ondrej/php5

而且問題HandlerSocket的插入: 1.循環 2中創建的索引,如果你做插入查詢通過HandlerSocket的更好手動設置ID(自動遞增)

0

哇!這是很多關於兄弟的信息。我不知道我是否有你的問題的權利,但如果我有那麼下面這段代碼將實現只有更好的效果相同:

$name = md5(rand(0, 1000)); 
$price = rand(0, 1000); 

try{ 

    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

    for($i=0, $i<100, $i++){ 

     $sql = "INSERT INTO products (name, price) VALUES (:name, :price)"; 
     $stmt = $db->prepare($sql); 
     $stmt->execute(array(':name'=>$name[$i], ':price'=>$price[$i])); 

     echo $db->lastInsertId(); 

    } 

}catch(PDOException $e){ 


    print_r($db->errorInfo()); 

    echo 'An error occured'.$e->getMessage(); 

} 

給它一個嘗試,並告訴我你得到了什麼。

+0

失敗時我得到這個:'陣列 ( [0] => 00000 [1] => [2] => ) 錯誤occuredSQLSTATE [HY000]:常規錯誤:2013丟失連接到MySQL服務器在查詢期間' – tuchk4

+0

順便說一句。如果我運行腳本表單瀏覽器 - 失敗。如果表單控制檯 - 一切正常。我想用nginx + php-fpm的問題? – tuchk4

+0

是所有必要的還是項目要求? – awsmketchup