Comment puis-je obtenir le SQL d'une PreparedStatement?
J'ai une méthode en Java avec la signature de méthode suivante:
private static ResultSet runSQLResultSet(String sql, Object... queryParams)
L'ouverture d'une connexion, construit une PreparedStatement
à l'aide de l'instruction sql et les paramètres de la queryParams
de longueur variable tableau, l'exécute, met la ResultSet
(dans un CachedRowSetImpl
), ferme la connexion, et retourne le jeu de résultats du cache.
J'ai la manipulation d'exception dans la méthode qui enregistre les erreurs. J'journal de l'instruction sql en tant que partie du journal, car il est très utile pour le débogage. Mon problème est que l'enregistrement de la variable de Chaîne sql
journaux le modèle de déclaration ?'s au lieu des valeurs réelles. Je veux ouvrir une session le réelle instruction a été exécutée (ou essayé de l'exécuter).
Alors... Est-il possible d'obtenir le véritable instruction SQL qui sera exécutée par un PreparedStatement
? (Sans le construire moi-même. Si je ne peux pas trouver un moyen d'accéder à la PreparedStatement's
SQL, je vais probablement jusqu'à la fin de la construire moi-même dans mon catch
es.)
- Si vous êtes à la rédaction de droite code JDBC, je vous conseille de regarder Apache commons dbutils commons.apache.org/dbutils. Il simplifie le code JDBC grandement.
- Dupe: stackoverflow.com/questions/218113/...
Vous devez vous connecter pour publier un commentaire.
À l'aide de déclarations préparées à l'avance, il n'y a pas de "requête SQL" :
Mais il n'y a pas de re-construction d'un vrai requête SQL -- ni sur le Java côté, ni sur le côté de la base de données.
Donc, il n'y a aucun moyen d'obtenir le prêt de l'instruction SQL -- comme il n'existe pas de telles SQL.
Fin de débogage, les solutions sont soit de :
PreparedStatement
exemple?execute()
méthode au cours de votre session de débogage.C'est nulle part défini dans l'API JDBC contrat, mais si vous avez de la chance, le pilote JDBC en question peut renvoyer le SQL complète simplement en appelant
PreparedStatement#toString()
. I. e.Au moins, MySQL 5.x et PostgreSQL 8.x pilotes JDBC pour la soutenir. Cependant, la plupart des autres pilotes JDBC ne le supporte pas. Si vous en avez un, alors votre meilleur pari est d'utiliser Log4jdbc ou P6Spy.
Alternativement, vous pouvez aussi écrire une fonction générique qui prend un
Connection
, une chaîne SQL et la déclaration de valeurs et qui renvoie unPreparedStatement
après l'enregistrement de la chaîne SQL et les valeurs. Le coup d'envoi exemple:et l'utiliser comme
Une autre alternative est de mettre en œuvre une coutume
PreparedStatement
qui s'enroule (orne) le réelPreparedStatement
sur la construction et remplace toutes les méthodes pour qu'il appelle les méthodes de la réelPreparedStatement
et recueille les valeurs dans tous lessetXXX()
méthodes et paresseusement construit le "réel" chaîne SQL à chaque fois que l'un desexecuteXXX()
méthodes est appelée (tout un travail, mais la plupart des IDE fournit autogenerators pour décorateur méthodes, Eclipse n'). Enfin, il suffit de l'utiliser à la place. C'est aussi, fondamentalement, ce que P6Spy et consorts font déjà sous le capot.logger.debug(sql + " " + Arrays.asList(values))
- je suis à la recherche d'un moyen de journal de l'instruction sql avec des paramètres déjà intégrées. Sans boucle, moi-même et remplacer les points d'interrogation.PreparedStatement
à chaque fois. Ne pas être pas si efficace coz point de l'ensemble dePreparedStatement
est de créer une fois et de ré-utiliser partout?Je suis à l'aide de Java 8, pilote JDBC de MySQL connector v. 5.1.31.
Je peut obtenir une vraie chaîne SQL à l'aide de cette méthode:
On en revient donc qch comme ceci:
Apache Derby
?Si vous êtes l'exécution de la requête et attend une
ResultSet
(vous êtes dans ce scénario, au moins), alors vous pouvez simplement appelerResultSet
'sgetStatement()
comme suit:La variable
executedQuery
contiendra la déclaration qui a été utilisé pour créer leResultSet
.Maintenant, je me rends compte de cette question est assez vieux, mais j'espère que cela aide quelqu'un..
J'ai extrait ma sql à partir de PreparedStatement à l'aide de preparedStatement.toString() Dans mon cas toString() renvoie la Chaîne de caractères comme ceci:
Maintenant, j'ai créé une méthode (Java 8), qui est à l'aide de regex extraire de la requête et des valeurs et de les mettre dans la map:
Cette méthode retourne la carte où nous avons des paires clé-valeur:
Maintenant - si vous souhaitez valeurs de la liste, vous pouvez tout simplement utiliser:
Si votre preparedStatement.toString() est différent de celui dans mon cas, c'est juste une question de "réglage" regex.
Très en retard 🙂 mais vous pouvez obtenir la version d'origine de SQL à partir d'un OraclePreparedStatementWrapper par
oracle.jdbc.driver.OraclePreparedStatementWrapper
n'est pas public dans oracle.jdbc.le pilote. Ne peut pas être accessible depuis l'extérieur du paquet. Comment utilisez-vous cette Classe?À L'Aide De PostgreSQL 9.6.x avec l'officiel du pilote Java
42.2.4
:Montrera le SQL avec l' ? déjà remplacés, ce qui est ce que je cherchais.
Venez d'ajouter à cette réponse de couvrir les postgres cas.
Je n'aurais jamais pensé que ça pourrait être si simple.
Si vous utilisez MySQL, vous pouvez vous connecter les requêtes à l'aide de MySQL query log. Je ne sais pas si d'autres fournisseurs proposent cette fonctionnalité, mais les chances sont qu'ils font.
J'ai mis en place le code suivant pour l'impression SQL à partir de PrepareStatement
Extrait de Code pour convertir SQL PreparedStaments avec la liste des arguments. Il fonctionne pour moi
Simplement fonction:
C'est bien aussi pour preparedStatement.
.toString()
avec un couple de lignes supplémentaires pour tromper des personnes non compétentes, et a été déjà répondu il y a longtemps.Je suis en utilisant Oralce 11g et ne parvenais pas à obtenir la valeur finale de SQL à partir de la PreparedStatement. Après la lecture de @Pascal MARTIN réponse, je comprends pourquoi.
J'ai juste abandonné l'idée d'utiliser des PreparedStatement et utilisé un simple programme de formatage de texte qui convenait parfaitement à mes besoins. Voici mon exemple:
Vous trouver la sqlInParam peut être construit de manière dynamique dans un (for,while) en boucle j'ai juste fait de la plaine simple d'obtenir le point de l'utilisation de la MessageFormat classe de servir comme un modèle de chaîne de formateur de table de la requête SQL.
((OraclePreparedStatementWrapper) myPreparedStatement).getOriginalSql()
Pour ce faire, vous avez besoin d'une Connexion JDBC et/ou le pilote qui prend en charge la journalisation du sql à un faible niveau.
Prendre un coup d'oeil à log4jdbc