Java PreparedStatement et SUR le DOUBLE de la CLÉ de mise à JOUR: comment savoir si la ligne a été insérée ou mise à jour?
Avoir code suivant, comment puis-je savoir si la méthode execute() a entraîné d'insertion ou de mise à jour?:
Connection c = DriverManager.getConnection(connectionString);
PreparedStatement st = c.prepareStatement("INSERT INTO `table`(`field1`) VALUES (?) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);");
st.setString(1,"some value");
st.execute();
Merci d'avance.
Vous devez vous connecter pour publier un commentaire.
De considérer les éléments suivants MySQL table de test:
existant avec les données de l'échantillon comme suit:
Avec la connexion par défaut
compensateOnDuplicateKeyUpdateCounts=false
(décrit ici) le code Java suivantproduit est le suivant sortie de la console
Maintenant, exécutez de nouveau le même code avec les valeurs de paramètre
et la sortie de la console est
Cela démontre que
.executeUpdate
peut vraiment revenir 2 si l'index unique provoque une ligne existante à être mis à jour. Si vous avez besoin d'aide avec votre réelle code de test, alors vous devez éditer votre question afin de l'inclure.Modifier
Plus loin l'essai révèle que
.executeUpdate
retourne 1 siCela peut être confirmé par des tests de code de deux fois dans une rangée, avec les mêmes valeurs de paramètre. Notez que le
UPDATE ... id = LAST_INSERT_ID(id)
"truc" n'a s'assurer que la bonneid
valeur est retournée.Ce qui explique probablement OP résultats du test si la valeur insérée est la valeur de clé UNIQUE.
executeUpdate
de toujours renvoyer les 2 sur la mise à jour vous devez vous assurer que la mise à JOUR en fait change quelque chose. Un candidat évident serait unlastUpdated
colonne de tenir la date/heure de la dernière modification (insert ou update). (2) Comme je l'ai dit, leSELECT_LAST_INSERT_ID()
la fonction t travail, même siexecuteUpdate
retourne 1 sur la mise à jour, donc c'est pas vraiment un problème.executeUpdate
, ou de la documentation de MySQL Connector/J?compensateOnDuplicateKeyUpdateCounts
propriété de configuration décrit ici qui sonne comme il pourrait produire des résultats plus proche de ce que vous attendez si elle est activée (par défaut, il n'est pas).Utilisation executeUpdate au lieu qu'elle retourne un
int
nombre de lignes.Mise à JOUR de 1: Selon le MySQL INSERT ... SUR le DOUBLE de la CLÉ de mise à JOUR de la documentation:
Mise à JOUR 2:
INSERT IGNORE
peut aussi être un option:executeUpdate
doit retourner 1 lorsqu'une nouvelle ligne est insérée et 0 quand il y a un doublon.INSERT ... ON DUPLICATE KEY
requêtes.executeUpdate()
renvoie 1 si une nouvelle ligne est insérée et qu'elle renvoie 2 si une ligne est mise à jour. L'exemple de code dans votre question pourrait être trompeur, car si la ligne existe déjà alors il n'y a vraiment rien d'autre à faire changer.executeUpdate()
peut retourner une valeur inattendue. Si vous pouvez créer un exemple de requête qui illustre le mieux votre problème, merci d'éditer votre question afin de l'inclure.UPDATE id=LAST_INSERT_ID(id)
si sur un double de la clé primaire est mis à jour. Un peu de chance avecINSERT IGNORE
?LAST_INSERT_ID()
"truc" est tout simplement une façon de s'assurer queLAST_INSERT_ID()
renvoie laid
valeur de l'enregistrement, même si c'était une ligne existante (et pas d'INSERT a été effectivement réalisés). Voir l'exemple dans ma réponse pour plus de détails.