2009-10-31 13 views
5

मैं नियमित तौर पर एक json फ़ीड को पार्स कर रहा हूँ और केवल फ़ीड से नवीनतम उपयोगकर्ताओं डालने और मौजूदा उपयोगकर्ताओं की अनदेखी करने की जरूरत है।एसक्यूएल: तालिका में केवल नई पंक्तियां/रिकॉर्ड डालें?

मैं मैं क्या जरूरत है ON DUPLICATE KEY UPDATE या INSERT IGNORE कुछ खोज पर आधारित है लगता है, लेकिन मैं काफी यकीन है कि यही कारण है कि मैं पूछ रहा हूँ नहीं कर रहा हूँ - तो उदाहरण के लिए:

users 
1  John 
2  Bob 

आंशिक JSON:

{ userid:1, name:'John' }, 
{ userid:2, name:'Bob' }, 
{ userid:3, name:'Jeff' } 

इस फ़ीड मैं केवल जेफ सम्मिलित करना चाहते हैं से। मैं सभी उपयोगकर्ताओं के माध्यम से एक साधारण लूप कर सकता हूं और एक साधारण चयन क्वेरी कर सकता हूं और देख सकता हूं कि उपयोगकर्ता आईडी पहले से ही तालिका में है, अगर मैं एक आईएनएसईआरटी नहीं करता हूं, हालांकि मुझे संदेह है कि यह एक कुशल और व्यावहारिक विधि नहीं होगी।

वैसे, मैं डेटाबेस बातचीत के लिए Zend_Db उपयोग कर रहा हूँ अगर किसी को भी एक विशिष्ट जवाब पूरा करने के लिए चाहते हैं :) मैं हालांकि एक सामान्य सामरिक समाधान आपत्ति नहीं है।

उत्तर

5

ON DUPLICATE KEY UPDATE विकल्प आप डेटाबेस के लिए बनाम डालने निर्णय अद्यतन उल्लेख करने के लिए अनुमति देता है:

INSERT INTO table (userid, name) VALUES (2, 'Bobby'); 
    ON DUPLICATE KEY UPDATE name = 'Bobby'; 

, नाम फ़ील्ड में 'बॉबी' को अद्यतन होता अगर userid 2 के साथ एक प्रविष्टि पहले से मौजूद है।

आप INSERT IGNORE के लिए एक विकल्प के रूप में उपयोग कर सकते हैं यदि आप अद्यतन करने के लिए एक noneffective आपरेशन की आपूर्ति:

INSERT INTO table (userid, name) VALUES (2, 'Bobby'); 
    ON DUPLICATE KEY UPDATE name = name; 

यह कुछ भी नहीं होता अगर userid 2 पहले से ही मौजूद है इस प्रकार की चेतावनी और अन्य त्रुटियों के कारण निगलने से परहेज INSERT IGNORE का उपयोग करते समय आपको मिल जाएगा।


एक अन्य विकल्प REPLACE होगा:

REPLACE INTO table (userid, name) VALUES (2, 'Bobby'); 

यह एक सामान्य डालने करना होगा अगर userid 2 अभी तक मौजूद नहीं है। यदि यह अस्तित्व में है, तो यह पहले पुरानी प्रविष्टि को हटा देगा और फिर एक नया डालेंगे।


ध्यान रखें कि दोनों संस्करण SQL के लिए MySQL विशिष्ट एक्सटेंशन हैं।

0

पाश में, आप एक अद्यतन पहले कर सकते हैं, यदि कोई पंक्ति प्रभावित है, जिसका अर्थ यह एक नई प्रविष्टि है। उन 'असफल अपडेट' का ट्रैक रखें, फिर उन्हें नई प्रविष्टियों के रूप में डालें।

मैं Zend_Db से परिचित नहीं हूँ, लेकिन मुझे लगता है यह लौट सकते हैं एक अद्यतन प्रभावित चाहे कितने पंक्ति (यों)।

INSERT IGNORE INTO table (userid, name) VALUES (2, 'Bob'); 

userid 2 पहले से ही मौजूद है, तो इसे अनदेखा और अगले डालने पर चलते देगा:

+0

किसी तरह मैं पढ़ने में भूलना यदि पाया गया तो मौजूदा उपयोगकर्ताओं को अपडेट करने की आवश्यकता के लिए सवाल, और नया के रूप में डालें। अच्छा ... नीचे मतदान –

2

आप एक प्राथमिक या अद्वितीय कुंजी के रूप में उपयोगकर्ता आईडी को परिभाषित करने और की तरह कुछ का उपयोग करने की आवश्यकता है।

तुम भी पर अपनी मेज स्कीमा पर नकली चाबी अद्यतन का उपयोग कर सकते हैं। एक अन्य विकल्प संभवतः वाक्यविन्यास में उपयोग करने के लिए उपयोग किया जा सकता है।

REPLACE INTO table (userid, name) VALUES (2, 'Bob'); 

इस निवेशन के लिए, अगर रिकॉर्ड पहले से मौजूद है तो फिर से डालने से पहले उसे हटा देंगे की कोशिश करेंगे।

+0

क्या 'INSERT IGNORE' Zend_Db में समर्थित है? –

+0

ईमानदारी से, नोफीड। –

+0

'आईजीएनओआर' डीबी इंजन को त्रुटियों के बजाए चेतावनी जारी करने का कारण बनता है, इसलिए क्वेरी का निष्पादन बंद नहीं होगा। इस दृष्टिकोण की कमी यह है कि * किसी भी * त्रुटि का सामना अनदेखा/चेतावनी में बदल दिया जाएगा, न केवल एक डुप्लिकेट कुंजी। –

4

Zend फ्रेमवर्क के लिए, मैं क्या एक कोशिश/डालने बयान की पकड़ है और अपवाद कोड के आधार पर आगे की कार्रवाई:

class Application_Model_DbTable_MyModel extends Zend_Db_Table_Abstract 

    public function insert($aData, $bIgnore = false) 
    { 

     try 
     { 
      $id = parent::insert($aData); 
     } 
     catch(Zend_Db_Statement_Mysqli_Exception $e) 
     { 
      // code 1062: Mysqli statement execute error : Duplicate entry 
      if($bIgnore && $e->getCode() == 1062) 
      { 
       // continue; 
      } 
      else 
      { 
       throw $e; 
      } 
     } 
     return !empty($id) ? $id : false; 
    } 
} 
+0

आपको सख्त मानकों के कारण $ bIgnore छोड़ना होगा: Your_Model :: insert() की घोषणा Zend_Db_Table_Abstract :: insert (array $ data) के साथ संगत होना चाहिए ... – bensiu

1

मेरे समाधान:

/** 
* Perform an insert with the IGNORE word 
* 
* @param $data array 
* @return number the number of rows affected 
*/ 
public function insertIgnore(array $data) 
{ 
    // Start of query 
    $sql = sprintf("INSERT IGNORE INTO %s (", $this->getAdapter()->quoteIdentifier($this->info('name'))); 
    // Retrieve column identifiers 
    $identifiers = array_keys($data); 
    foreach ($identifiers as $key => $value) { 
     // Quote identifier 
     $identifiers[$key] = $this->getAdapter()->quoteIdentifier($value); 
    } 
    // Concat column identifiers 
    $sql .= implode(', ', $identifiers); 
    $sql .= ") VALUES ("; 
    foreach ($data as $key => $value) { 
     // Quote values 
     $data[$key] = $this->getAdapter()->quote($value); 
    } 
    // Concat values identifiers 
    $sql .= implode(', ', $data); 
    $sql .= ")"; 
    // Process the query 
    return $this->getAdapter()->query($sql)->rowCount(); 
} 
संबंधित मुद्दे