2011-01-11 16 views
10

मैं पैरामीटरयुक्त इनपुट का उपयोग करने के लिए कुछ हार्ड-कोड किए गए प्रश्नों को स्विच करने की कोशिश कर रहा हूं, लेकिन मैंने एक समस्या में भाग लिया है: आप पैरामीटरयुक्त थोक आवेषण के लिए इनपुट कैसे प्रारूपित करते हैं?थोक पैरामीटरयुक्त प्रविष्टियां

वर्तमान में, कोड इस तरह दिखता है:

$sql = 'INSERT INTO my_table (field1, field2, field3) VALUES '; 
$parameters = array(); 
$data = array(); 
while ($my_condition) 
{ 
    $parameters[] = '(?, ?, ?)'; 
    $data[] = value1; 
    $data[] = value2; 
    $data[] = value3; 
} 

if (!empty($parameters)) 
{ 
    $sql .= implode(', ', $parameters); 
    $stmt = sqlsrv_prepare($my_connection, $sql, $data); 
    sqlsrv_execute($stmt); 
} 

वहाँ एक बेहतर तरीका पैरामिट्रीकृत के साथ एक थोक डालने पूरा करने के लिए है:

$data_insert = "INSERT INTO my_table (field1, field2, field3) "; 
$multiple_inserts = false; 
while ($my_condition) 
{ 
    if ($multiple_inserts) 
    { 
     $data_insert .= " UNION ALL "; 
    } 

    $data_insert .= " SELECT myvalue1, myvalue2, myvalue3 "; 
} 

$recordset = sqlsrv_query($my_connection, $data_insert); 

एक संभावित समाधान (How to insert an array into a single MySQL Prepared statement w/ PHP and PDO से संशोधित) प्रतीत होता है प्रश्नों?

+1

एक संभावित समाधान, तैयार बयान के लिए विशिष्ट , "एकल तैयार, एकाधिक निष्पादन" –

+0

मैं लेनदेन-हैंडलिंग की आवश्यकता को सीमित करने के लिए ऐसा करने से बचने की कोशिश कर रहा था। यदि कोई भी आवेषण विफल रहता है, तो पूरा ऑपरेशन विफल होना चाहिए। –

+0

क्या लेनदेन? –

उत्तर

5

ठीक है, आपके पास तीन विकल्प हैं।

  1. एक बार बनाएं - एकाधिक निष्पादित करें। असल में, आप एक पंक्ति के लिए एक बार सम्मिलित करते हैं, फिर इसे निष्पादित पंक्तियों पर लूप करें। चूंकि SQLSERVER एक्सटेंशन तैयार होने के बाद किसी क्वेरी के पुन: बाध्यकारी का समर्थन नहीं करता है (आपको dirty hacks with references करना होगा) जो कि सबसे अच्छा विकल्प नहीं हो सकता है।

  2. एक बार बनाएं - एक बार निष्पादित करें। असल में, आप अपने उदाहरण में कहा गया है कि एक विशाल डालने का निर्माण करें, इसे एक बार बांधें, और इसे निष्पादित करें। यह थोड़ा गंदा है और तैयार किए गए कुछ फायदे बताते हैं। हालांकि, विकल्प 1 से संदर्भों की आवश्यकता के कारण, मैं यह करूँगा। मुझे लगता है कि परिवर्तनीय संदर्भों पर निर्भर होने के बजाय एक विशाल क्वेरी बनाने के लिए क्लीनर है।

  3. एकाधिक बनाएं - एकाधिक निष्पादित करें। असल में, आप जिस विधि को कर रहे हैं उसे लें, और प्रत्येक इतने सारे रिकॉर्ड क्वेरी को दोबारा तैयार करने के लिए इसे ट्वीक करें। यह अत्यधिक बड़े प्रश्नों को रोकता है और प्रश्नों को "बैच" करता है। इस तरह तो कुछ:

    $sql = 'INSERT INTO my_table (field1, field2, field3) VALUES '; 
    $parameters = array(); 
    $data = array(); 
    
    $execute = function($params, $data) use ($my_connection, $sql) { 
        $query = $sql . implode(', ', $parameters); 
        $stmt = sqlsrv_prepare($my_connection, $query, $data); 
        sqlsrv_execute($stmt); 
    } 
    
    while ($my_condition) { 
        $parameters[] = '(?, ?, ?)'; 
        $data[] = value1; 
        $data[] = value2; 
        $data[] = value3; 
        if (count($parameters) % 25 == 0) { 
         //Flush every 25 records 
         $execute($parameters, $data); 
         $parameters = array(); 
         $data = array(); 
        } 
    } 
    if (!empty($parameters)) { 
        $execute($sql, $parameters, $data); 
    } 
    

या तो विधि पर्याप्त होगा। जो भी आपको लगता है वह आपकी आवश्यकताओं को सर्वोत्तम रूप से फिट करता है ...

+1

सिर्फ स्पष्टीकरण के लिए: विकल्प 2 और 3 दोनों में, SQL कथन इस तरह कुछ दिखाई देगा (अगर इसे स्क्रीन पर मुद्रित किया गया था): 'mytable (फ़ील्ड 1, फ़ील्ड 2, फ़ील्ड 3) में INSERT VALUES (?,?,?) , (?,?,?), (?,?,?), आदि 'को पारित सरणी द्वारा भरने के लिए। क्या वो सही है? –

+0

@Zac: हाँ, यह सही है। तीसरे समूहों में से अधिकांश समूह होंगे (आप डेटा आकार के आधार पर ट्विक कर सकते हैं)। दूसरे में आपके पास पंक्तियां होंगी ... – ircmaxell

+0

सभी मान 'PDO :: PARAM_STR' के रूप में डाले गए हैं, है ना? प्रकार कैसे निर्दिष्ट करें? –

2

क्यों न केवल "एक बार तैयार करें, एकाधिक निष्पादित करें" विधि का उपयोग न करें। मैं तुम्हें यह करने के लिए या तो सभी असफल या सब काम चाहते है, लेकिन यह लेनदेन के साथ कि संभाल करने के लिए मुश्किल बिल्कुल नहीं है:

http://www.php.net/manual/en/pdo.begintransaction.php

http://www.php.net/manual/en/pdo.commit.php

http://www.php.net/manual/en/pdo.rollback.php

+0

यह मुश्किल नहीं है, लेकिन यह इस कोड में जटिलता का स्तर जोड़ता है जिसकी वास्तव में आवश्यकता नहीं है। थोक सम्मिलन मेरी समस्या का सबसे सुंदर समाधान है, यह सिंटैक्स का मामला है जिसे मैं निश्चित नहीं था। –

+0

प्लस यह मूल 'sqlsrv' एक्सटेंशन का उपयोग कर रहा है जो दुनिया में सबसे स्वच्छ चीज़ नहीं है (यदि वह पीडीओ का उपयोग कर रहा था, संभवतः, लेकिन मूल वर्गों में कुछ वर्गों में मूल वर्ग की कमी है) ... – ircmaxell

+1

यदि बिंदु इसका पैरामीटरिज्ड प्रश्नों पर जाना है, क्यों एक ही समय में पीडीओ में नहीं जाते? "जटिलता" के लिए, यदि कोई निष्पादन() विफल होने पर कॉल को जोड़ना मुश्किल नहीं है, और यदि ऐसा होता है तो रोलबैक() और फिर किसी भी अन्य त्रुटि को संभालने की आवश्यकता होती है। – Stephen

संबंधित मुद्दे