फ्लाई पर इसे बनाकर बल्क इंसर्ट स्टेटमेंट क्वेरी तैयार करना संभव है, लेकिन इसमें कुछ तरकीबें हैं। सबसे महत्वपूर्ण बिट्स str_pad()
using का उपयोग कर रहे हैं चर लंबाई की एक क्वेरी स्ट्रिंग बनाने के लिए, और call_user_func_array()
. का उपयोग करके कॉल करने के लिए bind_param()
पैरामीटर की एक चर संख्या के साथ।
function insertBulkPrepared($db, $table, $fields, $types, $values) {
$chunklength = 500;
$fieldcount = count($fields);
$fieldnames = '`'.join('`, `', $fields).'`';
$prefix = "INSERT INTO `$table` ($fieldnames) VALUES ";
$params = '(' . str_pad('', 3*$fieldcount - 2, '?, ') . '), ';
$inserted = 0;
foreach (array_chunk($values, $fieldcount*$chunklength) as $group) {
$length = count($group);
if ($inserted != $length) {
if ($inserted) $stmt->close();
$records = $length / $fieldcount;
$query = $prefix . str_pad('', 3*$length + 2*($records - 1), $params);
#echo "\n<br>Preparing '" . $query . "'";
$stmt = $db->prepare($query);
if (!$stmt) return false;
$binding = str_pad('', $length, $types);
$inserted = $length;
}
array_unshift($group, $binding);
#echo "\n<br>Binding " . var_export($group, true);
$bound = call_user_func_array(array($stmt, 'bind_param'), $group);
if (!$bound) return false;
if (!$stmt->execute()) return false;
}
if ($inserted) $stmt->close();
return true;
}
यह फ़ंक्शन आपका $db
लेता है एक mysqli
. के रूप में उदाहरण के लिए, एक तालिका का नाम, फ़ील्ड नामों की एक सरणी और मानों के संदर्भों की एक सपाट सरणी। यह प्रति क्वेरी 500 रिकॉर्ड तक सम्मिलित करता है, जब संभव हो तो तैयार किए गए कथनों का पुन:उपयोग करता है। यह true
लौटाता है यदि सभी प्रविष्टियां सफल हुईं, या false
यदि उनमें से कोई असफल रहा। चेतावनी:
- तालिका और फ़ील्ड नाम बच नहीं गए हैं; मैं यह सुनिश्चित करने के लिए आप पर छोड़ता हूं कि उनमें बैकटिक्स नहीं हैं। सौभाग्य से, उन्हें कभी भी उपयोगकर्ता इनपुट से नहीं आना चाहिए।
- यदि लंबाई
$values
. है$fields
. की लंबाई का एक भी गुणज नहीं है , अंतिम हिस्सा शायद तैयारी के चरण में विफल हो जाएगा। - इसी तरह,
$types
. की लंबाई पैरामीटर$fields
. की लंबाई से मेल खाना चाहिए ज्यादातर मामलों में, खासकर जब उनमें से कुछ अलग होते हैं। - यह असफल होने के तीन तरीकों के बीच अंतर नहीं करता है। यह न तो ट्रैक करता है कि कितने इंसर्ट सफल हुए और न ही यह किसी त्रुटि के बाद जारी रखने का प्रयास करता है।
इस फ़ंक्शन को परिभाषित करने के साथ, आपके उदाहरण कोड को कुछ इस तरह से बदला जा सकता है:
$inserts = array();
for ($j = 0; $j < $abilitiesMax - 2; $j++) {
$inserts[] = &$abilityArray[$i]['match_id'];
$inserts[] = &$abilityArray[$i]['player_slot'];
$inserts[] = &$abilityArray[$i][$j]['ability'];
$inserts[] = &$abilityArray[$i][$j]['time'];
$inserts[] = &$abilityArray[$i][$j]['level'];
}
$fields = array('match_id', 'player_slot', 'ability', 'time', 'level');
$result = insertBulkPrepared($db, 'abilities', $fields, 'iiiii', $inserts);
if (!$result) {
echo "<p>$db->error</p>";
echo "<p>ERROR: when trying to insert abilities query</p>";
}
वे एम्परसेंड महत्वपूर्ण हैं, क्योंकि mysqli_stmt::bind_param
संदर्भों की अपेक्षा करता है, जो call_user_func_array
. द्वारा प्रदान नहीं किए गए हैं PHP के हाल के संस्करणों में।
आपने हमें मूल तैयार विवरण नहीं दिया है, इसलिए आपको संभवतः तालिका और फ़ील्ड नामों को समायोजित करने की आवश्यकता है। ऐसा भी लगता है कि आपका कोड $i
. पर एक लूप के अंदर बैठता है; उस स्थिति में, केवल for
लूप को बाहरी लूप के अंदर होना चाहिए। यदि आप अन्य पंक्तियों को लूप के बाहर लेते हैं, तो आप $inserts
को बनाने के लिए थोड़ी अधिक मेमोरी का उपयोग करेंगे। सरणी, अधिक कुशल बल्क इंसर्ट के बदले में।
insertBulkPrepared()
. को फिर से लिखना भी संभव है एक बहु-आयामी सरणी को स्वीकार करने के लिए, संभावित त्रुटि के एक स्रोत को समाप्त करना, लेकिन इसके लिए सरणी को खंडित करने के बाद इसे समतल करना आवश्यक है।