讓我們想象一下,我們應該使用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服務器?
可能有許多重複61的原因。這將有助於發佈您的實際代碼。這不是,對嗎? – Galen
您只需在循環前準備一次該語句。無需準備100次:) –
你的意思是它總是停留在61? – dbf