2008-11-19 7 views
44

मैं ज़ेंड फ्रेमवर्क 1.5 में ON DUPLICATE KEY UPDATE का उपयोग करना चाहता हूं, क्या यह संभव है?क्या ज़ेंड फ्रेमवर्क 1.5 में "INSERT ... डिप्लीकेट कुंजी अपडेटेट" करने का कोई तरीका है?

उदाहरण

INSERT INTO sometable (...) 
VALUES (...) 
ON DUPLICATE KEY UPDATE ... 

उत्तर

49

मैं Zend के लिए काम किया है और विशेष रूप से Zend_Db पर काफ़ी काम किया।

नहीं, ON DUPLICATE KEY UPDATE वाक्यविन्यास के लिए कोई एपीआई समर्थन नहीं है। इस मामले के लिए, आपको बस query() का उपयोग करना होगा और स्वयं को पूरा SQL कथन बनाएं।

मैं एसक्यूएल में घुमावदार मूल्यों के रूप में एसक्यूएल में इंटरपोलिंग मूल्यों की अनुशंसा नहीं करता हूं। क्वेरी पैरामीटर का प्रयोग करें।

संपादित करें: आप VALUES() अभिव्यक्तियों का उपयोग कर पैरामीटर को दोहराने से बच सकते हैं।

$sql = "INSERT INTO sometable (id, col2, col3) VALUES (:id, :col2, :col3) 
    ON DUPLICATE KEY UPDATE col2 = VALUES(col2), col3 = VALUES(col3)"; 

$values = array("id"=>1, "col2"=>327, "col3"=>"active"); 
+0

हाँ वह यह है कि क्या मैं भी किया था, अगर वहाँ था Zend_Db की _... एक विधि है कि है कि कार्यक्षमता तो शायद बजाय प्रदान करता है मैं वास्तव में सोच रहा था $ db-> डालने() का उपयोग करने के लिए हम $ db-> insertOrUpdate() ... केवल एक विचार का उपयोग कर सकते हैं। – danielrsmith

+1

नहीं, Zend_Db में ऐसी कोई विधि नहीं है। जेडएफ उत्पाद का लक्ष्य हमेशा 80% सबसे आम मामलों के लिए सरल समाधान प्रदान करना था। –

+1

आप इसे बढ़ा सकते हैं और आसानी से इस सुविधा को जोड़ सकते हैं;) –

5

@ बिल करविन: महान समाधान! लेकिन सवाल संकेतों के बजाय नामित प्लेसहोल्डर्स (": आईडी", ": col1", ...) का उपयोग करना अधिक होगा। Array_marge द्वारा आपको मानों को डुप्लिकेट करने की आवश्यकता नहीं होगी। इसके अलावा यदि "VALUES" के बजाय "INSERT" के "SET" वाक्यविन्यास का उपयोग करना है, तो कोड किसी भी फ़ील्ड के लिए स्वचालित रूप से जेनरेट होने के लिए सरल हो जाता है।

$sql = 'INSERT INTO sometable SET id = :id, col2 = :col2, col3 = :col3 
    ON DUPLICATE KEY UPDATE id = :id, col2 = :col2, col3 = :col3'; 
+0

मेरा मानना ​​है कि उस एडाप्टर पर निर्भर करता है जिसका आप उपयोग कर रहे हैं –

6

एक साइडबार के रूप में, आप ON DUPLICATE KEY UPDATE खंड को सरल बनाने और VALUES() का उपयोग करके प्रसंस्करण की राशि अपनी स्क्रिप्ट करने की जरूरत को कम कर सकते हैं:

$sql = 'INSERT INTO ... ON DUPLICATE KEY UPDATE id = VALUES(id), col2 = VALUES(col2), col3 = VALUES(col3)'; 

अधिक जानकारी के लिए http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html देखें।

-6

आप बस कुछ इस तरह कर सकते हैं: अपने आईडी पर

सेट अद्वितीय सूचकांक

और फिर

try { 
    do insert here 
} catch (Exception $e) { 
    do update here 
} 
1

इस बजाय का उपयोग करें:

REPLACE INTO sometable SET field ='value'..... 

यह अगर अद्यतन करेगा मौजूद है या नहीं तो बस डालें। यह मानक mysql api का एक हिस्सा है।

+4

नहीं, यह नहीं होगा। प्रतिस्थापित किसी मौजूदा मिलान पंक्ति को हटा दें और एक नया सम्मिलित करें। यदि आप सभी मानों को सम्मिलित नहीं करते हैं, तो इसका परिणाम अवांछित व्यवहार होगा। उदाहरण: आपके पास 'time_created' वाली तालिका है। यदि आप मान सेट किए बिना अपडेट का उपयोग करते हैं, तो यह वही रहेगा जब आपने पंक्ति बनाई थी। यदि आप 'REPLACE' का उपयोग करते हैं, तो पंक्ति हटा दी जाएगी, एक नया डाला जाएगा और' time_created' वर्तमान समय पर सेट किया जाएगा। – apfelbox

3
$arrayData = array('column1' => value1, 'column2' => value2, ...) 

class Model_Db_Abstract extends Zend_Db_Table_Abstract 
{ 
    protected $_name; 
    protected $_primaryKey; 

    public function insertOrUpdate($arrayData) 
    { 
     $query = 'INSERT INTO `'. $this->_name.'` ('.implode(',',array_keys($arrayData)).') VALUES ('.implode(',',array_fill(1, count($arrayData), '?')).') ON DUPLICATE KEY UPDATE '.implode(' = ?,',array_keys($arrayData)).' = ?'; 
     return $this->getAdapter()->query($query,array_merge(array_values($arrayData),array_values($arrayData))); 
    } 

} 

उपयोग:

जैसे। Model_Db_Contractors.php

class Model_Db_Contractors extends Model_Db_Abstract 
{ 

    protected $_name = 'contractors'; 
    protected $_primaryKey = 'contractor_id'; 

    ... 
} 

IndexController.php

class IndexController extends Zend_Controller_Action 
{ 
public function saveAction() 
{ 
    $contractorModel = new Model_Db_Contractors(); 
    $aPost = $this->getRequest()->getPost(); 

    /* some filtering, checking, etc */ 

    $contractorModel->insertOrUpdate($aPost); 
} 
} 
+1

यह सुनिश्चित नहीं है कि 'array_merge (array_values ​​($ arrayData), array_values ​​($ arrayData))' लेकिन 'array_values ​​($ arrayData)' – Patrioticcow

+0

पर्याप्त होगा, मुझे याद नहीं है कि मैंने इसे क्यों रखा है। – Pawel

+0

सरणी मानों के साथ क्वेरी के दूसरे भाग (ऑन डिप्लिकेट कुंजी अद्यतन ... =?) को बाध्य करने के लिए सही SQL क्वेरी के लिए आवश्यक है। – Pawel