3 回答

TA貢獻(xiàn)1874條經(jīng)驗(yàn) 獲得超12個贊
MySQL客戶端協(xié)議不允許進(jìn)行多個查詢。也就是說,您已經(jīng)執(zhí)行了查詢,并且已經(jīng)獲取了一些結(jié)果,但不是全部—然后嘗試執(zhí)行第二個查詢。如果第一個查詢?nèi)杂幸祷氐男校瑒t第二個查詢將收到錯誤。
客戶端庫通過在首次獲取時隱式獲取第一個查詢的所有行來解決此問題,然后后續(xù)獲取僅對內(nèi)部緩存的結(jié)果進(jìn)行迭代。這給他們提供了關(guān)閉游標(biāo)的機(jī)會(就MySQL服務(wù)器而言)。這就是“緩沖查詢”。這與使用fetchAll()相同,這兩種情況都必須在PHP客戶端中分配足夠的內(nèi)存以容納完整的結(jié)果集。
不同之處在于,緩沖的查詢將結(jié)果保存在MySQL客戶端庫中,因此,只有在依次提?。╢etch())每行之后,PHP才能訪問這些行。而fetchAll()立即為所有結(jié)果填充一個PHP數(shù)組,從而允許您訪問任何隨機(jī)行。
不使用fetchAll()的主要原因是結(jié)果可能太大而無法容納在您的PHP memory_limit中。但是看來您的查詢結(jié)果仍然只有一行,所以這應(yīng)該不是問題。
您可以先關(guān)閉closeCursor()以“放棄”結(jié)果,然后再獲取最后一行。MySQL服務(wù)器收到通知,可以在服務(wù)器端放棄該結(jié)果,然后可以執(zhí)行另一個查詢。在完成獲取給定結(jié)果集之前,您不應(yīng)該關(guān)閉closeCursor()。
另外:我注意到您在循環(huán)內(nèi)一遍又一遍地執(zhí)行$ stmt2,但是每次都會返回相同的結(jié)果。根據(jù)將循環(huán)不變代碼移出循環(huán)的原理,您應(yīng)該在開始循環(huán)之前執(zhí)行一次,并將結(jié)果保存在PHP變量中。因此,無論使用緩沖查詢還是fetchAll(),都無需嵌套查詢。
因此,我建議您以這種方式編寫代碼:
$sql ='SELECT temp_id FROM temp1';
$stmt2 = db::db()->prepare($sql);
$stmt2->execute();
$rs2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
$stmt2->closeCursor();
$sql='SELECT COUNT(*) AS valid FROM cities_has_zipcodes
WHERE cities_id=:cities_id AND zipcodes_id=:zipcodes_id';
$stmt1 = db::db()->prepare($sql);
foreach($data AS $row)
{
try
{
$stmt1->execute($row);
$rs1 = $stmt1->fetchAll(PDO::FETCH_ASSOC);
$stmt1->closeCursor();
syslog(LOG_INFO,'$rs1: '.print_r($rs1[0],1).' '.rand());
syslog(LOG_INFO,'$rs2: '.print_r($rs2[0],1).' '.rand());
}
catch(PDOException $e){echo(sql_error($e));}
}
注意我還使用了命名參數(shù)而不是位置參數(shù),這使得將$ row作為參數(shù)值數(shù)組進(jìn)行傳遞更加簡單。如果數(shù)組的鍵與參數(shù)名稱匹配,則只需傳遞數(shù)組即可。在舊版本的PHP中,您必須:在數(shù)組鍵中包含前綴,但是您不再需要該前綴。
無論如何,您應(yīng)該使用mysqlnd。它具有更多功能,具有更高的內(nèi)存效率,并且其許可證與PHP兼容。

TA貢獻(xiàn)2041條經(jīng)驗(yàn) 獲得超4個贊
我希望有一個比以下更好的答案。盡管其中一些解決方案可以“解決”問題,但它們并未回答有關(guān)導(dǎo)致此錯誤的原因的原始問題。
設(shè)置
PDO::ATTR_EMULATE_PREPARES=>true
(我不希望這樣做)設(shè)置
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
(對我不起作用)使用
PDOStatement::fetchAll()
(并非總是可取的)$stmt->closeCursor()
每次使用之后$stmt->fetch()
(大多數(shù)情況下可以使用,但是我仍然有幾種情況沒有使用)將PHP MySQL庫從php-mysql更改為php-mysqlnd(如果沒有更好的答案,我可能會怎么做)

TA貢獻(xiàn)1966條經(jīng)驗(yàn) 獲得超4個贊
我?guī)缀跤型瑯拥膯栴}。連接到數(shù)據(jù)庫后,我的第一個查詢返回空結(jié)果并刪除此錯誤。啟用緩沖區(qū)沒有幫助。
我的連接代碼是:
try {
$DBH = new PDO("mysql:host=$hostname;dbname=$db_name", $username, $password,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET utf8; SET NAMES utf8",
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_NUM));
}
catch(PDOException $e) { echo $e->getMessage(); }
我的解決方案是刪除初始命令:
PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET utf8; SET NAMES utf8"
這是正確的代碼:
try {
$DBH = new PDO("mysql:host=$hostname;dbname=$db_name", $username, $password,
array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_NUM));
}
catch(PDOException $e) { echo $e->getMessage(); }
并且MYSQL_ATTR_USE_BUFFERED_QUERY不是強(qiáng)制為true。設(shè)置為默認(rèn)值。
添加回答
舉報(bào)