AOP préparées pour l'INSERTION et SUR le DOUBLE de la CLÉ de mise à JOUR avec des espaces réservés nommés
J'aimerais commutateur AOP INSÉRER et mettre à JOUR des déclarations préparées à INSÉRER et SUR le DOUBLE de la CLÉ de mise à JOUR car je pense que ça va être beaucoup plus efficace que ce que je fais actuellement, mais je vais avoir de la difficulté à trouver la bonne syntaxe à utiliser avec des marqueurs nommés et bindParam.
J'ai trouvé plusieurs question similaire sur, mais je suis nouveau sur PDO et je ne pouvais pas réussi à adapter le code pour mes critères. C'est ce que j'ai essayé, mais ça ne fonctionne pas (il n'a pas d'insérer ou mettre à jour):
try {
$stmt = $conn->prepare('INSERT INTO customer_info (user_id, fname, lname) VALUES(:user_id, :fname, :lname)'
'ON DUPLICATE KEY UPDATE customer_info SET fname= :fname,
lname= :lname
WHERE user_id = :user_id');
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':fname', $_POST['fname'], PDO::PARAM_STR);
$stmt->bindParam(':lname', $_POST['lname'], PDO::PARAM_STR);
$stmt->execute();
}
C'est une version simplifiée de mon code (j'ai plusieurs requêtes, et chaque requête est compris entre 20 - 50 champs). Je suis actuellement à la mise à jour de la première et de vérifier si le nombre de lignes mises à jour est supérieure à 0 et si non, alors l'exécution de l'Insertion, et chacune de ces requêtes a son propre ensemble de bindParam consolidés.
- Ne pas réutiliser le même espace réservé à plusieurs endroits dans la même requête. Est votre AOP jeu de connexion pour lancer des exceptions? Sauf si vous avez un besoin réel pour
bindParam
,bindValue
ou d'un passage de paramètres par le biais deexecute
est un meilleur choix. - Quand vous dites que je ne devrais pas réutiliser le même espace réservé à de multiples endroits, voulez-vous dire que j'ai besoin d'avoir 2 jeux de bindParam déclarations? Je l'ai mis actuellement avec - catch(PDOException $e) {echo 'Erreur:' . $e->getMessage();} - et je ne reçois pas tous les messages d'erreur pour ce code.
- Il suffit de le mettre try/catch autour de la requête n'est pas assez. Voir gestion des Erreurs et le configurer pour lancer des exceptions en cas d'erreur.
- Pourriez-vous élaborer sur ce que tu veux dire? J'ai pensé à la façon dont je le fais dans la droite ligne avec ERRMODE_EXCEPTION dans le manuel, qui doit lancer une PDOException.
- Votre exemple ne montre pas ERRMODE_EXCEPTION à définir. C'est pourquoi j'ai demandé si votre connexion est configuré pour le faire. Si vous ne l'avez défini, rien n'est plus nécessaire, les problèmes devraient lancer des exceptions.
- Mon mauvais pour ne pas faire ça 😉 C'est me prendre un peu de temps pour obtenir une poignée sur PDO, et j'avais oublié que j'avais mis une partie de la gestion d'erreur dans le fichier de configuration.
- J'ai pris vos suggestions et commuté à bindValue, mais j'aimerais clarifier ce que vous disiez à propos de la différence bindParam vs bindValue, et passage de paramètres par le biais de l'exécuter. (J'avais initialement pas été en mesure d'obtenir le code pour travailler avec bindValue j'ai donc été à l'aide de bindParam)
- Voir cette question les différences entre les
bindParam
etbindValue
.$stmt->execute(array(':fname' => $_POST['fname']))
peut également être utilisé pour transmettre des variables liées. À mon avis,execute
est l'option la plus simple et devrait être préféré si vous en avez besoin les comportements spécifiques debindParam
oubindValue
. Votre kilométrage peut varier, bien sûr. - Merci pour ce lien - il si bien expliqué 🙂 j'étais sous l'impression que la liaison des valeurs ou des paramètres est plus sécurisé puis l'exécution d'un tableau. Suis-je trompé?
Vous devez vous connecter pour publier un commentaire.
Votre
ON DUPLICATE KEY
syntaxe n'est pas correcte.Vous n'avez pas besoin de mettre le nom de la table ou
SET
dans leON DUPLICATE KEY
clause, et vous n'avez pas besoin d'unWHERE
de l'alinéa (il a toujours les mises à jour de l'enregistrement avec le double de la clé).Voir http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
De vous a une erreur de syntaxe PHP: vous divisez la requête en deux chaînes.
Mise à JOUR:
Pour lier plusieurs paramètres:
Ensuite l'appeler:
bindParam()
dans une boucle pour lier le tout.bindMultiple
pour chaque variable que vous avez besoin de répéter dans le SQL. Vous avez besoin de répéter$_POST['fname']
et$_POST['lname']
, mais il n'y a qu'un$user_id
.bindParam
exige que la variable est une référence. Je viens de changerbindMultiple
pour refléter cela.bindValue()
il n'est pas judicieux de se référer à la même colonne ou d'une variable à plusieurs reprises, donc ce n'est pas un problème.À mon humble avis ci-dessous est la réponse appropriée pour toute personne venant à travers ce nouveau.
Remarque: cette déclaration suppose user_id est une CLÉ dans la table.
La DÉCLARATION, en effet, se tromper, mais l'on a accepté la réponse n'était pas tout à fait correct.
Si vous êtes l'insertion et la mise à jour en utilisant les mêmes valeurs (et pas de mise à jour avec des valeurs différentes), c'est la requête pseudo-code corrigé:
VALUES()
est plus facile quand vous avez besoin d'utiliser des paramètres. Mais comme une question de côté, fwiw vous n'avez pas besoin de casser votre chaîne de caractères en PHP comme vous le faites en Java. Vous pouvez mettre un multi-ligne de chaîne de caractères en un seul ensemble de citations.