Je suis en train d'analyser régulièrement un jeu JSON et je n'ai besoin d'insérer que les utilisateurs les plus récents de l'alimentation et d'ignorer les utilisateurs existants.
Je pense que ce dont j'ai besoin est partiel JSON: p> à partir de cet aliment, je veux seulement insérer Jeff. Je pourrais faire une boucle simple à travers tous les utilisateurs et faire une simple requête Sélectionner et voir si l'ID utilisateur est déjà dans la table, sinon je fais un insert, mais je soupçonne que ce ne sera pas une méthode efficace et pratique. P> Au fait, j'utilise zend_db pour l'interaction de la base de données si quelqu'un aimerait répondre à une réponse spécifique :) Cela ne vous dérange pas de solution stratégique générique. P> P> sur la mise à jour de clé en double code> ou
ou
Insérer Ignorer code> en fonction de la recherche mais je ne suis pas tout à fait sûr, c'est pourquoi je demande - donc par exemple: p>
5 Réponses :
Dans la boucle, vous pouvez d'abord faire une mise à jour, si aucune ligne affectée signifie que c'est une nouvelle entrée. Gardez une trace de ces «mises à jour échouées» puis effectuez une insertion d'eux comme de nouvelles entrées. P>
Je ne connais pas Zend_DB mais je suppose que cela peut retourner si une mise à jour a affecté combien de rangées. P>
D'une manière ou d'une autre, j'ai mal interprété la question de la nécessité de mettre à jour les utilisateurs existants si trouvé, sinon insérer comme neuf. bien ... a voté
Vous devez définir l'ID utilisateur comme une clé primaire ou unique et utiliser quelque chose comme: si l'utilisateur 2 existe déjà, il ignore et passera à l'insert suivant. P > Vous pouvez également utiliser sur la mise à jour de la clé en double sur votre schéma de table.
Est insérer Ignore code> pris en charge dans zend_db?
Le Ignorer code> entraînera des avertissements au lieu d'erreurs, de sorte que l'exécution de la requête ne s'arrête pas. Un inconvénient de cette approche est que toute erreur i> rencontrée sera ignoré / tourné vers l'avertissement, non seulement une clé en double.
@HENRIK: Je n'étais pas au courant des avertissements VS errors, mais j'ai fourni une méthode alternative pour accomplir la même chose sans utiliser Ignorer.
@eyze: J'écris simplement les alternatives aussi;)
@eyze: une correction mineure mais potentiellement importante - remplacer code> pas b> est une mise à jour en cas d'une clé existante, elle fera une suppression, suivie d'un insert.
Le mettrait à jour le champ Nom sur "Bobby", si une entrée avec Userid 2 déjà existe. P> Vous pouvez l'utiliser comme alternative à l'insertion code> Ignorer code> si vous fournissez une opération non-affective à la mise à jour: p> sur la mise à jour de la clé en double
alternative vous permet de renvoyer la décision de mise à jour par rapport à la base de données: REPLACE INTO table (userid, name) VALUES (2, 'Bobby');
Pour Zend Cadre, ce que je fais est un essai / attrape de l'instruction insertion et prenez des mesures supplémentaires en fonction du code d'exception:
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; } }
Vous devez abandonner $ Bignore en raison de standards stricts: déclaration de votre_model :: insert () doit être compatible avec zend_db_table_abstract :: insert (array $ données) dans ...
Ma solution:
/** * 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(); }