MySQL में एकाधिक अपडेट


388

मुझे पता है कि आप एक ही बार में कई पंक्तियों को सम्मिलित कर सकते हैं, क्या MySQL में एक बार में (जैसा कि एक क्वेरी में) कई पंक्तियों को अपडेट करने का एक तरीका है?

संपादित करें: उदाहरण के लिए मेरे पास निम्नलिखित हैं

Name   id  Col1  Col2
Row1   1    6     1
Row2   2    2     3
Row3   3    9     5
Row4   4    16    8

मैं निम्नलिखित सभी अपडेट को एक क्वेरी में संयोजित करना चाहता हूं

UPDATE table SET Col1 = 1 WHERE id = 1;
UPDATE table SET Col1 = 2 WHERE id = 2;
UPDATE table SET Col2 = 3 WHERE id = 3;
UPDATE table SET Col1 = 10 WHERE id = 4;
UPDATE table SET Col2 = 12 WHERE id = 4;

जवाबों:


651

हां, यह संभव है - आप INSERT ... ON DUPLICATE KEY UPDATE का उपयोग कर सकते हैं।

अपने उदाहरण का उपयोग करना:

INSERT INTO table (id,Col1,Col2) VALUES (1,1,1),(2,2,3),(3,9,3),(4,10,12)
ON DUPLICATE KEY UPDATE Col1=VALUES(Col1),Col2=VALUES(Col2);

22
अगर कोई डुप्लिकेट नहीं है, तो मैं नहीं चाहता कि पंक्ति को डाला जाए। आईडी क्या करना चाहिए? क्योंकि मैं किसी अन्य साइट से जानकारी प्राप्त कर रहा हूं जो आईडी के साथ तालिकाओं को बनाए रखता है। मैं उस आईडी के संबंध में मान डाल रहा हूं। यदि साइट पर नए रिकॉर्ड हैं तो मैं केवल आईडी डालने और अन्य सभी जानकारी को छोड़कर समाप्त कर दूंगा। अगर और केवल अगर आईडी के लिए कोई प्रविष्टि है तो इसे अपडेट करना चाहिए और इसे छोड़ देना चाहिए। मैं क्या करूँ?
जयपाल चंद्रन

33
नोट: यह उत्तर यह भी मानता है कि आईडी प्राथमिक कुंजी है
JM4

11
@ जयपालचंद्रन आपको INSERT IGNORE का उपयोग ON DUPLICATE KEY UPDATE के साथ करना चाहिए। dev.mysql.com/doc/refman/5.5/en/insert.html
हरलन डोबरेव

16
@HaralanDobrev INSERT IGNORE का उपयोग अभी भी गैर डुप्लिकेट किए गए रिकॉर्ड सम्मिलित करता है। जिससे जयपाल बचना चाहता था। INSERT IGNORE बस किसी भी त्रुटि को चेतावनी में बदल देता है :( stackoverflow.com/questions/548541/…
Takehiro Adachi

2
यह उत्तर मानता है कि आईडी एक अद्वितीय कुंजी है (जैसा कि अन्य ने कहा कि प्राथमिक हो सकती है) लेकिन इससे भी महत्वपूर्ण बात यह है कि कोई अन्य अद्वितीय कुंजी नहीं है। यदि कोई हैं, तो यह कार्यों में एक स्पैनर फेंक सकता है।
स्टीव होर्वाथ

129

चूंकि आपके पास गतिशील मूल्य हैं, इसलिए आपको अपडेट किए जाने वाले कॉलम के लिए IF या CASE का उपयोग करना होगा। यह थोड़े बदसूरत हो जाता है, लेकिन यह काम करना चाहिए।

अपने उदाहरण का उपयोग करते हुए, आप ऐसा कर सकते हैं:

अद्यतन तालिका SET Col1 = CASE आईडी सेट करें 
                          जब १ १ 
                          जब २ २ 
                          जब 4 से 10 
                          ELSE Col1 
                        समाप्त, 
                 Col2 = CASE आईडी 
                          जब 3 3 
                          ४ से १२ होने पर 
                          ELSE Col2 
                        समाप्त
             कहाँ आईडी (1, 2, 3, 4) में;

शायद गतिशील अद्यतन करने के लिए लिखने के लिए बहुत सुंदर नहीं है, लेकिन आवरण की कार्यक्षमता पर दिलचस्प नज़र ...
me_

1
@ user2536953, यह गतिशील अद्यतन के लिए भी अच्छा हो सकता है। उदाहरण के लिए, मैंने उस समाधान को php में पाश में प्रयोग किया:$commandTxt = 'UPDATE operations SET chunk_finished = CASE id '; foreach ($blockOperationChecked as $operationID => $operationChecked) $commandTxt .= " WHEN $operationID THEN $operationChecked "; $commandTxt .= 'ELSE id END WHERE id IN ('.implode(', ', array_keys(blockOperationChecked )).');';
Boolean_Type

86

प्रश्न पुराना है, फिर भी मैं इस विषय को दूसरे उत्तर के साथ आगे बढ़ाना चाहूंगा।

मेरा कहना है कि इसे प्राप्त करने का सबसे आसान तरीका है, लेन-देन के साथ कई प्रश्नों को लपेटना। स्वीकृत उत्तर INSERT ... ON DUPLICATE KEY UPDATEएक अच्छा हैक है, लेकिन इसकी कमियों और सीमाओं से अवगत होना चाहिए:

  • जैसा कि कहा जा रहा है, यदि आप उन पंक्तियों के साथ क्वेरी लॉन्च करना चाहते हैं जिनकी प्राथमिक कुंजियाँ तालिका में मौजूद नहीं हैं, तो क्वेरी नए "अर्ध-बेक्ड" रिकॉर्ड सम्मिलित करती है। संभवतः यह वह नहीं है जो आप चाहते हैं
  • यदि आपके पास डिफ़ॉल्ट मान के बिना शून्य फ़ील्ड के साथ एक तालिका है और इस फ़ील्ड को क्वेरी में स्पर्श नहीं करना चाहते हैं, तो आप "Field 'fieldname' doesn't have a default value"MySQL चेतावनी प्राप्त करेंगे भले ही आप एक भी पंक्ति सम्मिलित न करें। यह आपको मुश्किल में डाल देगा, अगर आप सख्त होना चाहते हैं और अपने ऐप में mysql चेतावनियों को रनटाइम अपवाद में बदल दें।

मैंने सुझाए गए तीन वेरिएंटों में से कुछ के लिए कुछ प्रदर्शन परीक्षण किए, जिनमें वेरिएंट, INSERT ... ON DUPLICATE KEY UPDATE"केस / जब / फिर" क्लॉज और लेनदेन के साथ एक भोली दृष्टिकोण शामिल है। आपको यहां अजगर कोड और परिणाम मिल सकते हैं । कुल मिलाकर निष्कर्ष यह है कि केस स्टेटमेंट वाला वेरिएंट दो अन्य वेरिएंट की तुलना में दोगुना होता है, लेकिन इसके लिए सही और इंजेक्शन-सुरक्षित कोड लिखना काफी कठिन है, इसलिए मैं व्यक्तिगत रूप से सबसे सरल दृष्टिकोण से जुड़ा हुआ हूं: लेनदेन का उपयोग करना।

संपादित करें: डाकुसन की खोज यह साबित करती है कि मेरे प्रदर्शन के अनुमान काफी मान्य नहीं हैं। कृपया इस उत्तर को दूसरे, अधिक विस्तृत शोध के लिए देखें।


लेनदेन का उपयोग करना, बहुत अच्छा (और सरल) टिप!
मटोरेस

क्या होगा यदि मेरी तालिकाएँ InnoDB प्रकार नहीं हैं?
टोमेन्स

1
क्या कोई ऐसा लेन-देन कर सकता है जो इस तरह का लेनदेन करता है? और / या केस स्टेटमेंट वाले संस्करण के लिए एक इंजेक्शन-सुरक्षित कोड के लिए कोड?
फ्रैंकोइस एम।

1
मुझे इस पोस्ट में गति के बारे में दी गई जानकारी झूठी लगती है। मैंने इसके बारे में नीचे एक पोस्ट में लिखा है। stackoverflow.com/questions/3432/multiple-updates-in-mysql/…
डाकुसन

1
@ डाकुसन, शानदार जवाब। मेरे परिणामों को विस्तार देने, टिप्पणी करने और ठीक करने के लिए बहुत धन्यवाद।
रोमन इमानकुलोव

72

निश्चित नहीं है कि एक अन्य उपयोगी विकल्प का उल्लेख अभी तक क्यों नहीं किया गया है:

UPDATE my_table m
JOIN (
    SELECT 1 as id, 10 as _col1, 20 as _col2
    UNION ALL
    SELECT 2, 5, 10
    UNION ALL
    SELECT 3, 15, 30
) vals ON m.id = vals.id
SET col1 = _col1, col2 = _col2;

4
यह सबसे अच्छा है। खासकर यदि आप किसी अन्य SQL क्वेरी से अपडेट के लिए मान खींच रहे हैं जैसा कि मैं कर रहा था।
v010dya

1
यह एक बड़े पैमाने पर स्तंभों के साथ एक तालिका के अपडेट के लिए बहुत अच्छा था। मैं शायद भविष्य में इस क्वेरी का भरपूर उपयोग करूंगा। धन्यवाद!
कैस्पर विल्कस

मैंने इस प्रकार की क्वेरी की कोशिश की है। लेकिन जब रिकॉर्ड 30k बाउंड्री सर्वर तक पहुंचते हैं तो बंद हो जाता है। क्या कोई और उपाय है?
भाविन चौहान

यह बहुत अच्छा लग रहा है। मैं इसे WHERE क्लॉज़ के साथ संयोजित करने का प्रयास करूँगा जहाँ प्राथमिक कुंजियाँ अद्यतन नहीं हैं, लेकिन बदलने के लिए कॉलम की पहचान करने के लिए उपयोग किया जाता है।
nl-x

@BhavinChauhan क्या आपने मुद्दे को दरकिनार करने के लिए ज्वाइन-सेलेक्ट के बजाय एक अस्थायी तालिका का उपयोग करने की कोशिश की है?
nl-x

41

निम्नलिखित में से सभी InnoDB पर लागू होते हैं।

मुझे लगता है कि 3 अलग-अलग तरीकों की गति जानना महत्वपूर्ण है।

3 विधियाँ हैं:

  1. INSERT: INUPERT ON DUPLICATE KEY UPDATE
  2. लेन-देन: जहाँ आप एक लेनदेन के भीतर प्रत्येक रिकॉर्ड के लिए एक अद्यतन करते हैं
  3. मामले: जिसमें आप एक मामला / जब प्रत्येक अलग रिकॉर्ड के लिए एक अद्यतन

मैंने अभी-अभी इसका परीक्षण किया था, और INSERT विधि मेरे लिए ट्रांजेक्शन विधि की तुलना में 6.7 गुना तेज थी । मैंने 3,000 और 30,000 पंक्तियों के सेट पर कोशिश की।

परिवहन विधि अभी भी प्रत्येक व्यक्तिगत क्वेरी को चलाने के लिए है, जिसमें समय लगता है, हालांकि यह निष्पादन में, या स्मृति में परिणाम को बैच देता है। परिवहन विधि भी प्रतिकृति और क्वेरी लॉग दोनों में बहुत महंगा है।

इससे भी बदतर यह मामला विधि थी 41.1x सम्मिलित करें विधि की तुलना में धीमी w / 30,000 रिकॉर्ड (6.1x लेन-देन की तुलना में धीमी)। और MyISAM में 75x धीमा। INSERT और CASE विधियाँ ~ 1,000 के रिकॉर्ड में भी टूट गईं। यहां तक ​​कि 100 रिकॉर्ड में, CASE विधि बारेली तेजी से है।

इसलिए सामान्य तौर पर, मुझे लगता है कि INSERT विधि सबसे अच्छा और उपयोग करने में आसान है। प्रश्न पढ़ने में छोटे और आसान होते हैं और केवल 1 क्वेरी की कार्रवाई करते हैं। यह InnoDB और MyISAM दोनों पर लागू होता है।

बोनस सामान:

INSERT गैर-डिफ़ॉल्ट-फ़ील्ड समस्या का समाधान अस्थायी रूप से प्रासंगिक SQL मोड को बंद करना है SET SESSION sql_mode=REPLACE(REPLACE(@@SESSION.sql_mode,"STRICT_TRANS_TABLES",""),"STRICT_ALL_TABLES",""):। sql_modeयदि आप इसे वापस करने की योजना बनाते हैं तो पहले बचत करना सुनिश्चित करें ।

जैसा कि अन्य टिप्पणियों के लिए मैंने देखा है कि कहते हैं कि Auto_increment INSERT पद्धति का उपयोग करके ऊपर जाता है, ऐसा लगता है कि InnoDB में मामला है, लेकिन MyISAM नहीं।

परीक्षण चलाने के लिए कोड इस प्रकार है। यह php दुभाषिया उपरि हटाने के लिए .SQL फाइलें भी आउटपुट करता है

<?
//Variables
$NumRows=30000;

//These 2 functions need to be filled in
function InitSQL()
{

}
function RunSQLQuery($Q)
{

}

//Run the 3 tests
InitSQL();
for($i=0;$i<3;$i++)
    RunTest($i, $NumRows);

function RunTest($TestNum, $NumRows)
{
    $TheQueries=Array();
    $DoQuery=function($Query) use (&$TheQueries)
    {
        RunSQLQuery($Query);
        $TheQueries[]=$Query;
    };

    $TableName='Test';
    $DoQuery('DROP TABLE IF EXISTS '.$TableName);
    $DoQuery('CREATE TABLE '.$TableName.' (i1 int NOT NULL AUTO_INCREMENT, i2 int NOT NULL, primary key (i1)) ENGINE=InnoDB');
    $DoQuery('INSERT INTO '.$TableName.' (i2) VALUES ('.implode('), (', range(2, $NumRows+1)).')');

    if($TestNum==0)
    {
        $TestName='Transaction';
        $Start=microtime(true);
        $DoQuery('START TRANSACTION');
        for($i=1;$i<=$NumRows;$i++)
            $DoQuery('UPDATE '.$TableName.' SET i2='.(($i+5)*1000).' WHERE i1='.$i);
        $DoQuery('COMMIT');
    }

    if($TestNum==1)
    {
        $TestName='Insert';
        $Query=Array();
        for($i=1;$i<=$NumRows;$i++)
            $Query[]=sprintf("(%d,%d)", $i, (($i+5)*1000));
        $Start=microtime(true);
        $DoQuery('INSERT INTO '.$TableName.' VALUES '.implode(', ', $Query).' ON DUPLICATE KEY UPDATE i2=VALUES(i2)');
    }

    if($TestNum==2)
    {
        $TestName='Case';
        $Query=Array();
        for($i=1;$i<=$NumRows;$i++)
            $Query[]=sprintf('WHEN %d THEN %d', $i, (($i+5)*1000));
        $Start=microtime(true);
        $DoQuery("UPDATE $TableName SET i2=CASE i1\n".implode("\n", $Query)."\nEND\nWHERE i1 IN (".implode(',', range(1, $NumRows)).')');
    }

    print "$TestName: ".(microtime(true)-$Start)."<br>\n";

    file_put_contents("./$TestName.sql", implode(";\n", $TheQueries).';');
}

1
तुम यहाँ यहोवा का काम कर रहे हो;) बहुत सराहना की।
चिली

GoLang और PHP के बीच कुछ प्रदर्शन का परीक्षण, MariaDB पर 40k पंक्तियों का उपयोग करते हुए, मुझे PHP पर 2 सेकंड और golang पर 6 से अधिक सेकंड मिल रहे थे .... खैर, मुझे हमेशा बताया गया था कि GoLang PHP की तुलना में तेजी से चलेगा !!! अतः, मुझे आश्चर्य है कि प्रदर्शन में सुधार कैसे किया जाए ... INSERT का उपयोग करके ... DUPLICATE KEY UPDATE पर ... मुझे गोलंग पर 0.74 सेकेंड मिले और PHP पर 0.86 सेकेंड !!!!
डिएगो फेवरो

1
मेरे कोड का बिंदु SQL परिणामों को कड़ाई से निर्धारित करने के लिए समय के परिणामों को सीमित करना है, न कि भाषा या पुस्तकालयों के लिए कोड। GoLang और PHP 2 पूरी तरह से अलग-अलग भाषाएं हैं जो पूरी तरह से अलग चीजों के लिए हैं। PHP एक एकल रन स्क्रिप्टिंग वातावरण के लिए है, जो कि ज्यादातर सीमित और निष्क्रिय कचरा संग्रह के साथ एक ही धागे पर है। GoLang का अभिप्राय लंबे समय से चल रहे संकलित अनुप्रयोगों के साथ आक्रामक कचरा संग्रह और बहुभाषी प्राथमिक भाषा सुविधाओं में से एक के रूप में है। वे भाषा की कार्यक्षमता और कारण के संदर्भ में मुश्किल से अलग हो सकते हैं। [जारी]
डाकुसन

इसलिए अपने परीक्षण चलाते समय, SQL कथन के लिए "क्वेरी" फ़ंक्शन कॉल को सख्ती से करने के लिए गति माप को सीमित करना सुनिश्चित करें। स्रोत कोड के अन्य भागों की तुलना और अनुकूलन जो कड़ाई से क्वेरी कॉल नहीं हैं, सेब और संतरे की तुलना करने जैसा है। यदि आप अपने परिणामों को इस तक सीमित रखते हैं (तार पहले से तैयार और जाने के लिए तैयार हैं) तो परिणाम बहुत समान होने चाहिए। उस बिंदु पर कोई भी मतभेद भाषा की SQL लाइब्रेरी की गलती है, और जरूरी नहीं कि भाषा ही हो। मेरी राय में, डुप्लीकेट समाधान पर INSERT था और हमेशा सबसे अच्छा विकल्प होगा। [Cont]
1919

जैसा कि गोलांग पर आपकी टिप्पणी तेजी से हो रही है, यह एक अविश्वसनीय रूप से व्यापक बयान है जो इन भाषाओं और उनके डिजाइनों की कई घटनाओं या बारीकियों को ध्यान में नहीं रखता है। जावा एक व्याख्या की गई भाषा है, लेकिन मुझे 15 साल पहले पता चला था कि यह वास्तव में कुछ परिदृश्यों में गति से लगभग (और शायद कभी-कभी हरा) सी से मेल खा सकता है। और सी एक संकलित भाषा है, और कोडर के अलावा सबसे निचले स्तर की सिस्टम भाषाओं में सबसे आम है। मुझे वास्तव में बहुत पसंद है कि GoLang क्या कर रहा है और इसमें निश्चित रूप से सबसे आम प्रणालियों में से एक बनने और अनुकूलित करने की शक्ति और तरलता है [Cont]
Dakusan

9

एक अस्थायी तालिका का उपयोग करें

// Reorder items
function update_items_tempdb(&$items)
{
    shuffle($items);
    $table_name = uniqid('tmp_test_');
    $sql = "CREATE TEMPORARY TABLE `$table_name` ("
        ."  `id` int(10) unsigned NOT NULL AUTO_INCREMENT"
        .", `position` int(10) unsigned NOT NULL"
        .", PRIMARY KEY (`id`)"
        .") ENGINE = MEMORY";
    query($sql);
    $i = 0;
    $sql = '';
    foreach ($items as &$item)
    {
        $item->position = $i++;
        $sql .= ($sql ? ', ' : '')."({$item->id}, {$item->position})";
    }
    if ($sql)
    {
        query("INSERT INTO `$table_name` (id, position) VALUES $sql");
        $sql = "UPDATE `test`, `$table_name` SET `test`.position = `$table_name`.position"
            ." WHERE `$table_name`.id = `test`.id";
        query($sql);
    }
    query("DROP TABLE `$table_name`");
}

8
UPDATE table1, table2 SET table1.col1='value', table2.col1='value' WHERE table1.col3='567' AND table2.col6='567'

इसके लिए फिर से काम करना चाहिए।

कई तालिकाओं के लिए MySQL मैनुअल में एक संदर्भ है ।


6

कोई एक क्वेरी में कई कथनों का उल्लेख क्यों नहीं करता है ?

Php में, आप multi_querymysqli उदाहरण की विधि का उपयोग करते हैं ।

से php पुस्तिका

MySQL वैकल्पिक रूप से एक स्टेटमेंट स्ट्रिंग में कई स्टेटमेंट रखने की अनुमति देता है। एक बार में कई स्टेटमेंट भेजने से क्लाइंट-सर्वर राउंड ट्रिप कम हो जाते हैं, लेकिन विशेष हैंडलिंग की आवश्यकता होती है।

यहाँ अद्यतन 30,000 कच्चे में अन्य 3 तरीकों की तुलना में परिणाम है। कोड यहाँ पाया जा सकता है जो @Dakusan के उत्तर पर आधारित है

लेन-देन: 5.5194580554962
डालें: 0.20669293403625
केस: 16.474853992462
मल्टी: 0.0412278175354

जैसा कि आप देख सकते हैं, कई कथन क्वेरी उच्चतम उत्तर की तुलना में अधिक कुशल है।

यदि आपको इस तरह त्रुटि संदेश मिलता है:

PHP Warning:  Error while sending SET_OPTION packet

आपको max_allowed_packetmysql config फाइल में वृद्धि करने की आवश्यकता हो सकती है जो मेरी मशीन में है /etc/mysql/my.cnfऔर फिर mysqld को पुनरारंभ करें।


सभी नीचे की तुलना INSERT परीक्षण के खिलाफ की जाती है। मैं सिर्फ एक ही स्थिति में परीक्षण चलाता था और लेनदेन के बिना, यह 300 पंक्तियों पर 145x धीमा था और 3000 पंक्तियों के लिए 753x धीमा था। मैंने मूल रूप से 30,000 पंक्तियों के साथ शुरू किया था, लेकिन मैं खुद को दोपहर का भोजन बनाने के लिए गया और वापस आया और यह अभी भी चल रहा था। यह व्यक्तिगत प्रश्नों को चलाने के रूप में समझ में आता है और प्रत्येक डेटाबेस को व्यक्तिगत रूप से निस्तब्धता से महँगा होगा। खासकर प्रतिकृति के साथ। लेनदेन को चालू करना हालांकि एक बड़ा अंतर है। 3,000 पंक्तियों में इसे 1.5x अधिक और 30,000 पंक्तियों में 2.34x पर लिया गया । [जारी रखा]
डाकुसन

लेकिन आप इसके बारे में सही थे कि यह तेज़ है (लेनदेन के साथ)। 3,000 और 30,000 दोनों पंक्तियों में यह सब कुछ लेकिन INSERT विधि की तुलना में तेज़ था। 30,000 प्रश्नों की तुलना में 1 क्वेरी चलाने से बेहतर परिणाम प्राप्त करने का कोई तरीका नहीं है, भले ही वे एक विशेष म्यांमार एपीआई कॉल में बैच रहे हों। केवल 300 पंक्तियों में चल रहा था, यह अन्य सभी तरीकों (मेरी आश्चर्य की बात) की तुलना में बहुत तेज था, जो कैस विधि के समान ग्राफ वक्र के बारे में है। इसे तेजी से 2 तरीकों से समझाया जा सकता है। पहली बात यह है कि INSERT विधि अनिवार्य रूप से "ON DUPLICATE KEY [
कॉन्टेस्ट

UPDATE "दोनों एक" INSERT "और" UPDATE "के कारण। दूसरा यह है कि यह SQL प्रोसेसर में केवल अनुक्रमणिका लुकअप के कारण एक बार में 1 पंक्ति को संपादित करने के लिए कम काम है। मुझे यकीन नहीं है कि आपको मुझसे अलग परिणाम कैसे मिले। लेकिन आपका अतिरिक्त परीक्षण ठोस दिखता है। मुझे वास्तव में यह भी पता नहीं है कि प्रतिकृति इस कॉल को कैसे संभालती है। यह केवल कॉल कॉल करने के लिए भी काम करेगा। सम्मिलित कॉल एकल
इंसर्ट

मैं एक लूप के लिए एक त्रुटि को संशोधित करने के लिए एक टेबल पर एक समय में 300 UPDATE कर रहा था जिसमें 41 सेकंड लगे। एक ही अद्यतन प्रश्नों को एक $mysqli->multi_query($sql)"0" सेकंड में लाना । हालाँकि, बाद के प्रश्न विफल हो गए, जिससे मुझे एक अलग "प्रोग्राम" बनाना पड़ा।
क्रिस के

धन्यवाद। मल्टी क्वेरी का उपयोग करके एक मिनट में लगभग 5k पंक्तियों (अधिक परीक्षण नहीं) को अपडेट करने में सक्षम था। अगर कोई PDO समाधान की तलाश में है: stackoverflow.com/questions/6346674/…
Scofield

3

एक सेटिंग है जिसे आप 'मल्टी स्टेटमेंट' कह सकते हैं जो MySQL के 'सेफ्टी मैकेनिज्म' को निष्क्रिय कर देता है जो कि (एक से अधिक) इंजेक्शन कमांड को रोकने के लिए लागू किया गया है। MySQL के 'शानदार' कार्यान्वयन के लिए विशिष्ट, यह उपयोगकर्ता को कुशल प्रश्न करने से भी रोकता है।

यहां ( http://dev.mysql.com/doc/refman/5.1/en/mysql-set-server-option.html ) सेटिंग के C कार्यान्वयन के बारे में कुछ जानकारी है।

यदि आप PHP का उपयोग कर रहे हैं, तो आप मल्टी स्टेटमेंट करने के लिए mysqli का उपयोग कर सकते हैं (मुझे लगता है कि php ने mysqli के साथ कुछ समय के लिए भेज दिया है)

$con = new mysqli('localhost','user1','password','my_database');
$query = "Update MyTable SET col1='some value' WHERE id=1 LIMIT 1;";
$query .= "UPDATE MyTable SET col1='other value' WHERE id=2 LIMIT 1;";
//etc
$con->multi_query($query);
$con->close();

उम्मीद है की वो मदद करदे।


4
यह अलग-अलग प्रश्नों को भेजने के समान है। अंतर केवल इतना है कि आप इसे सभी एक नेटवर्क पैकेट में भेजते हैं, लेकिन अपडेट को अलग प्रश्नों के रूप में संसाधित किया जाएगा। बेहतर है कि उन्हें एक लेन-देन में लपेटा जाए, फिर एक ही बार में तालिका में बदलाव शुरू कर दिया जाएगा।
15:55 बजे Marki555

3
उन्हें एक लेनदेन में कैसे लपेटें? हमें दिखाओ, कृपया।
टोमेएनएस

@TomeeNS mysqli::begin_transaction(..)क्वेरी भेजने से पहले और mysql::commit(..)बाद में उपयोग करें । या क्वेरी में ही START TRANSACTIONप्रथम और COMMITअंतिम कथन के रूप में उपयोग करें ।
जूहा पालोम्की

3

आप जिस आईडी को आप सम्मिलित करना चाहते हैं उसे देने के लिए उसी तालिका को अन्य नाम दे सकते हैं (यदि आप पंक्ति-दर-पंक्ति अपडेट कर रहे हैं:

UPDATE table1 tab1, table1 tab2 -- alias references the same table
SET 
col1 = 1
,col2 = 2
. . . 
WHERE 
tab1.id = tab2.id;

इसके अतिरिक्त, यह स्पष्ट होना चाहिए कि आप अन्य तालिकाओं से भी अपडेट कर सकते हैं। इस स्थिति में, अपडेट "चयन" कथन के रूप में दोगुना हो जाता है, जिससे आप उस तालिका से डेटा प्राप्त कर सकते हैं जिसे आप निर्दिष्ट कर रहे हैं। आप अपनी क्वेरी को अपडेट मानों में स्पष्ट रूप से बता रहे हैं, इसलिए दूसरी तालिका अप्रभावित है।


2

आप अद्यतनों पर जुड़ने का उपयोग करने में भी रुचि रख सकते हैं, जो संभव है।

Update someTable Set someValue = 4 From someTable s Inner Join anotherTable a on s.id = a.id Where a.id = 4
-- Only updates someValue in someTable who has a foreign key on anotherTable with a value of 4.

संपादित करें: यदि आपके द्वारा अपडेट किए जा रहे मान डेटाबेस में कहीं और से नहीं आ रहे हैं, तो आपको कई अपडेट क्वेरी जारी करनी होगी।



-1

उपयोग

REPLACE INTO`table` VALUES (`id`,`col1`,`col2`) VALUES
(1,6,1),(2,2,3),(3,9,5),(4,16,8);

कृपया ध्यान दें:

  • आईडी एक प्राथमिक अद्वितीय कुंजी होनी चाहिए
  • यदि आप तालिका को संदर्भित करने के लिए विदेशी कुंजियों का उपयोग करते हैं, तो REPLACE तो आवेषण को हटा देता है, इसलिए यह त्रुटि का कारण हो सकता है

-3

निम्नलिखित सभी पंक्तियों को एक तालिका में अद्यतन करेगा

Update Table Set
Column1 = 'New Value'

अगला एक सभी पंक्तियों को अद्यतन करेगा जहाँ Column2 का मान 5 से अधिक है

Update Table Set
Column1 = 'New Value'
Where
Column2 > 5

एक से अधिक टेबल अपडेट करने के सभी Unkwntech का उदाहरण है

UPDATE table1, table2 SET
table1.col1 = 'value',
table2.col1 = 'value'
WHERE
table1.col3 = '567'
AND table2.col6='567'

-3

हां .. यह संभव है कि DUPLICATE KEY UPDATE sql स्टेटमेंट पर INSERT का उपयोग किया जा सके .. वाक्य रचना: INSERT INTO table_name (a, b, c) VALUES (1,2,3), (4,5,6) ONUPLICATE KEY UPDATE a = मान (क), बी = मान (ख), ग = मान (ग)


-5
UPDATE tableName SET col1='000' WHERE id='3' OR id='5'

यह वह हासिल करना चाहिए जो आप देख रहे हैं। बस अधिक आईडी जोड़ें। मैंने इसका परीक्षण किया है।


-7
UPDATE `your_table` SET 

`something` = IF(`id`="1","new_value1",`something`), `smth2` = IF(`id`="1", "nv1",`smth2`),
`something` = IF(`id`="2","new_value2",`something`), `smth2` = IF(`id`="2", "nv2",`smth2`),
`something` = IF(`id`="4","new_value3",`something`), `smth2` = IF(`id`="4", "nv3",`smth2`),
`something` = IF(`id`="6","new_value4",`something`), `smth2` = IF(`id`="6", "nv4",`smth2`),
`something` = IF(`id`="3","new_value5",`something`), `smth2` = IF(`id`="3", "nv5",`smth2`),
`something` = IF(`id`="5","new_value6",`something`), `smth2` = IF(`id`="5", "nv6",`smth2`) 

// आप इसे php की तरह बना रहे हैं

$q = 'UPDATE `your_table` SET ';

foreach($data as $dat){

  $q .= '

       `something` = IF(`id`="'.$dat->id.'","'.$dat->value.'",`something`), 
       `smth2` = IF(`id`="'.$dat->id.'", "'.$dat->value2.'",`smth2`),';

}

$q = substr($q,0,-1);

तो आप एक क्वेरी के साथ छेद तालिका को अपडेट कर सकते हैं


मैं downvote नहीं किया था, लेकिन मुझे लगता है कि आपत्ति सेट कर यह आवश्यक नहीं है जब, करने के लिए है (और आप अब भी कर रहे हैं जब आप सेट कर रहे हैं somethingकरने के लिए something)
v010dya
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.