2008-11-19 12 views

Antwort

49

ich für Zend arbeitete und arbeitete speziell auf Zend_Db ziemlich viel.

Nein, es gibt keine API-Unterstützung für die Syntax ON DUPLICATE KEY UPDATE. In diesem Fall müssen Sie einfach query() verwenden und die vollständige SQL-Anweisung selbst erstellen.

Ich empfehle nicht, Werte in die SQL zu interpolieren, wie harvejs zeigt. Verwenden Sie Abfrageparameter.

Bearbeiten: Sie können die Wiederholung der Parameter vermeiden, indem Sie VALUES() Ausdrücke verwenden.

$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

Ja, das ist das, was ich auch getan habe, habe ich wirklich frage mich, ob es ein Verfahren zum Zend_Db _... war, die diese Funktionalität vielleicht stattdessen so bietet Mit $ db-> insert() können wir $ db-> insertOrUpdate() verwenden ... nur eine Idee. – danielrsmith

+1

Nein, es gibt keine solche Methode in Zend_Db. Das Ziel des ZF-Produkts war immer, einfache Lösungen für die 80% der Fälle zu finden. –

+1

Sie können es erweitern und diese Funktion einfach hinzufügen;) –

5

@ Bill Karwin: großartige Lösungen! Aber es wäre größer, wenn man anstelle von Fragenzeichen benannte Platzhalter (": id", ": col1", ...) verwendet. Dann müssten Sie die Werte nicht mit array_marge duplizieren. Auch wenn die "SET" -Syntax von "INSERT" anstelle von "VALUES" verwendet wird, wird der Code vereinfacht, automatisch für jede Menge von Feldern erzeugt zu werden.

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

Ich glaube, das hängt davon ab, den Adapter verwenden Sie –

6

Als Sidebar können Sie die ON DUPLICATE KEY UPDATE Klausel vereinfachen und reduzieren die Menge der Verarbeitung Skript von VALUES() mit tun muss:

$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 Siehe für weitere Informationen.

-6

können Sie einfach so etwas tun:

gesetzt eindeutigen Index für Ihre ID

und dann

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

Verwenden Sie stattdessen:

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

Dies wird aktualisiert, wenn existiert oder füge einfach ein, wenn nicht. Dies ist ein Teil der Standard-MySQL-API.

+4

Nein, wird es nicht. Ersetzen löscht alle vorhandenen übereinstimmenden Zeilen und fügt eine neue Zeile ein. Dies führt zu unerwünschtem Verhalten, wenn Sie nicht alle Werte eingeben. Beispiel: Sie haben eine Tabelle mit einem 'time_created'. Wenn Sie update verwenden, ohne den Wert zu setzen, bleibt es gleich, wenn Sie die Zeile erstellt haben. Wenn Sie 'REPLACE' verwenden, wird die Zeile entfernt, ein neues wird eingefügt und' time_created' wird auf die aktuelle Zeit gesetzt. – 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))); 
    } 

} 

ANWENDUNG:

zB. 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

nicht sicher, warum 'array_merge (array_values ​​($ arrayData), array_values ​​($ arrayData))' aber 'array_values ​​($ arrayData)' wird ausreichen – Patrioticcow

+0

Gute Frage, ich kann mich nicht erinnern, warum ich es dort hinstelle. – Pawel

+0

Es wird für die korrekte SQL-Abfrage benötigt, um den zweiten Teil der Abfrage (ON DUPLICATE KEY UPDATE ... =?) Mit Array-Werten zu binden. – Pawel

Verwandte Themen