MySQL क्लाइंट प्रोटोकॉल एक से अधिक क्वेरी को "प्रगति में" होने की अनुमति नहीं देता है। यानी, आपने एक क्वेरी निष्पादित की है और आपने कुछ परिणाम प्राप्त किए हैं, लेकिन सभी नहीं - फिर आप दूसरी क्वेरी निष्पादित करने का प्रयास करते हैं। यदि पहली क्वेरी में अभी भी वापस आने के लिए पंक्तियाँ हैं, तो दूसरी क्वेरी में एक त्रुटि होती है।
क्लाइंट लाइब्रेरी सभी . लाकर इससे निजात पा सकते हैं पहली क्वेरी की पंक्तियाँ पहले फ़ेच पर निहित रूप से होती हैं, और फिर बाद के फ़ेच केवल आंतरिक रूप से कैश्ड परिणामों पर पुनरावृति करते हैं। यह उन्हें कर्सर को बंद करने का अवसर देता है (जहाँ तक MySQL सर्वर का संबंध है)। यह "बफ़र्ड क्वेरी" है। यह उसी तरह काम करता है जैसे कि fetchAll () का उपयोग करते हुए, दोनों मामलों में पूर्ण परिणाम सेट रखने के लिए PHP क्लाइंट में पर्याप्त मेमोरी आवंटित करनी चाहिए।
अंतर यह है कि एक बफ़र की गई क्वेरी का परिणाम MySQL क्लाइंट लाइब्रेरी में होता है, इसलिए PHP पंक्तियों तक नहीं पहुंच सकता जब तक कि आप प्रत्येक पंक्ति को क्रमिक रूप से नहीं लाते। जबकि fetchAll() तुरंत सभी परिणामों के लिए एक PHP सरणी को पॉप्युलेट करता है, जिससे आप किसी भी यादृच्छिक पंक्ति तक पहुंच सकते हैं।
मुख्य कारण नहीं fetchAll() का उपयोग करने के लिए यह है कि परिणाम आपके PHP मेमोरी_लिमिट में फ़िट होने के लिए बहुत बड़ा हो सकता है। लेकिन ऐसा लगता है कि आपके क्वेरी परिणामों में वैसे भी केवल एक पंक्ति है, इसलिए यह कोई समस्या नहीं होनी चाहिए।
अंतिम पंक्ति प्राप्त करने से पहले आप परिणाम को "छोड़ने" के लिए कर्सर() को बंद कर सकते हैं। MySQL सर्वर को सूचित किया जाता है कि वह उस परिणाम को सर्वर साइड पर छोड़ सकता है, और फिर आप दूसरी क्वेरी निष्पादित कर सकते हैं। जब तक आप किसी दिए गए परिणाम सेट को प्राप्त नहीं कर लेते, तब तक आपको Cursor() को बंद नहीं करना चाहिए।
साथ ही:मैंने देखा है कि आप लूप के अंदर अपने $stmt2 को बार-बार निष्पादित कर रहे हैं, लेकिन यह हर बार एक ही परिणाम लौटाएगा। लूप-इनवेरिएंट कोड को लूप से बाहर ले जाने के सिद्धांत पर, आपको लूप शुरू करने से पहले इसे एक बार निष्पादित करना चाहिए था, और परिणाम को 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));}
}
नोट मैंने स्थितीय मापदंडों के बजाय नामित मापदंडों का भी उपयोग किया है, जो $row को पैरामीटर मानों की सरणी के रूप में पास करना आसान बनाता है। यदि सरणी की कुंजियाँ पैरामीटर नामों से मेल खाती हैं, तो आप केवल सरणी पास कर सकते हैं। PHP के पुराने संस्करणों में आपको :
. शामिल करना था सरणी कुंजियों में उपसर्ग, लेकिन अब आपको इसकी आवश्यकता नहीं है।
आपको वैसे भी mysqlnd का उपयोग करना चाहिए। इसमें अधिक विशेषताएं हैं, यह अधिक मेमोरी-कुशल है, और इसका लाइसेंस PHP के साथ संगत है।