आपको तब तक लाने की आवश्यकता है जब तक कि एक पंक्ति लाने का प्रयास विफल न हो जाए। मुझे पता है कि परिणाम सेट में आपके पास केवल एक पंक्ति हो सकती है और लगता है कि एक फ़ेच पर्याप्त है, लेकिन ऐसा नहीं है (जब आप असंबद्ध प्रश्नों का उपयोग कर रहे हों)। पीडीओ यह नहीं जानता कि अंत तक पहुंचने तक कितनी पंक्तियाँ हैं, जहाँ वह अगली पंक्ति लाने की कोशिश करता है, लेकिन यह विफल हो जाता है।
आपके पास शायद अन्य कथन हैं जहां आपने पूरी तरह से "प्राप्त करने में विफल होने तक" प्राप्त नहीं किया था। हां, मैं देख रहा हूं कि एक . के लिए फ़ेच विफल होने तक आप फ़ेच करते हैं बयानों में से, लेकिन इसका मतलब यह नहीं है कि आपने यह उन सभी के लिए किया है।
स्पष्टीकरण के लिए - जब आप निष्पादन() के माध्यम से कोई क्वेरी निष्पादित करते हैं, तो आप एक परिणाम सेट बनाते हैं जिसे डीबी से PHP में लाया जाना चाहिए। पीडीओ एक समय में (प्रति कनेक्शन) इनमें से केवल 1 "प्राप्त किए जाने की प्रगति में परिणाम सेट" को संभाल सकता है। इससे पहले कि आप निष्पादित करने के लिए एक अलग कॉल से एक अलग परिणाम सेट प्राप्त करना शुरू कर सकें, आपको परिणाम सेट को पूरी तरह से अंत तक लाने की आवश्यकता है।
जब आप "फ़ेच() को तब तक कॉल करते हैं जब तक कि एक भ्रूण() विफल नहीं हो जाता", तथ्य यह है कि आप परिणामों के अंत तक पहुंच गए हैं, पीडीओ द्वारा आंतरिक रूप से नोट किया जाता है जब अंतिम कॉल लाने के लिए() विफल हो जाता है क्योंकि कोई और परिणाम नहीं होता है। पीडीओ तब संतुष्ट होता है कि परिणाम पूरी तरह से प्राप्त होते हैं, और यह उस परिणाम सेट के लिए स्थापित किए गए PHP और डीबी के बीच जो भी आंतरिक संसाधन साफ कर सकता है, आपको अन्य प्रश्न बनाने/प्राप्त करने की इजाजत देता है।
पीडीओ बनाने के और भी तरीके हैं "एक फ़ेच() विफल होने तक कॉल फ़ेच ()"।
- बस fetchAll() का उपयोग करें, जो केवल सभी पंक्तियों को प्राप्त करता है, और इसलिए यह परिणाम सेट के अंत तक पहुंच जाएगा।
- या बस क्लोज कर्सर को कॉल करें ()
*यदि आप क्लोज़ कर्सर () के स्रोत को देखते हैं, तो डिफ़ॉल्ट कार्यान्वयन शाब्दिक रूप से केवल पंक्तियों को प्राप्त करता है और अंत तक पहुंचने तक उन्हें त्याग देता है। यह स्पष्ट रूप से c में लिखा गया है, लेकिन यह कमोबेश यही करता है:
function closeCursor() {
while ($row = $stmt->fetch()) {}
$this->stmtFullyFetched = true;
}
कुछ डीबी ड्राइवरों के पास एक अधिक कुशल कार्यान्वयन हो सकता है जिसके लिए उन्हें बहुत सी पंक्तियों को लाने की आवश्यकता नहीं होती है जिनकी कोई परवाह नहीं करता है, लेकिन यह डिफ़ॉल्ट तरीका है जो पीडीओ करता है। वैसे भी...
जब आप बफ़र किए गए प्रश्नों का उपयोग करते हैं तो आम तौर पर आपको ये समस्याएँ नहीं होती हैं। इसका कारण यह है कि बफर किए गए प्रश्नों के साथ, आपके द्वारा उन्हें निष्पादित करने के ठीक बाद, पीडीओ स्वचालित रूप से डीबी परिणामों को पूरी तरह से PHP मेमोरी में लाएगा, इसलिए यह स्वचालित रूप से आपके लिए "कॉल फ़ेच () जब तक कि एक फ़ेच () विफल नहीं हो जाता" भाग करता है। जब आप बाद में fetch() या fetchAll() स्वयं को कॉल करते हैं, तो यह डीबी से नहीं, PHP मेमोरी से परिणाम प्राप्त कर रहा है। तो मूल रूप से, बफ़र्ड प्रश्नों का उपयोग करते समय परिणाम सेट तुरंत पूरी तरह से प्राप्त किया जाता है, इसलिए एक ही समय में 1 से अधिक "प्राप्त होने की प्रगति में परिणाम सेट" होने का कोई अवसर नहीं है (क्योंकि PHP सिंगल थ्रेडेड है, इसलिए 2 प्रश्नों का कोई मौका नहीं है एक ही समय में चल रहा है)।
इसे देखते हुए:
$sql = "select * from test.a limit 1";
$stmt = $dbh->prepare($sql);
$stmt->execute(array());
परिणाम सेट को पूरी तरह से लाने के तरीके (यह मानते हुए कि आप केवल पहली पंक्ति चाहते हैं):
$row = $stmt->fetch();
$stmt->closeCursor();
या
list($row) = $stmt->fetchAll(); //tricky
या
$row = $stmt->fetch();
while ($stmt->fetch()) {}