Le curseur Python ne peut pas récupérer les résultats de la procédure stockée
P粉833546953
2023-08-24 14:22:59
<p>Pour une raison étrange, je ne parviens pas à obtenir les résultats d'un appel callproc dans une application de test Python. La procédure stockée dans MqSQL 5.2.47 ressemble à ceci : </p>
<pre class="brush:php;toolbar:false;">CREATE PROCEDURE `mytestdb`.`getperson` (IN personid INT)
COMMENCER
sélectionnez person.person_id,
personne.person_fname,
personne.person_mi,
personne.person_lname,
personne.persongender_id,
personne.personjob_id
de la personne
où personne.person_id = personid ;
FIN</pré>
<p>Maintenant, en utilisant PyCharm et Python 3.3, je n'arrive pas à récupérer quoi que ce soit lors de l'appel de cette procédure stockée. Ce code obtient le résultat souhaité : </p>
<pre class="brush:php;toolbar:false;">importer mysql.connector
cnx = mysql.connector.connect(user='root', host='127.0.0.1', database='mytestdb')
cnx._open_connection()
curseur = cnx.cursor()
curseur.execute("sélectionner * de la personne où personne.person_id = 1")
personnes = curseur.fetchall()
pour personne chez les personnes :
imprimer (personne)
cnx.close()</pre>
<p>Mais ce code a curseur.fetchall() ou curseur.fetchone()...</p>
<pre class="brush:php;toolbar:false;">importer mysql.connector
cnx = mysql.connector.connect(user='root', host='127.0.0.1', database='mytestdb')
cnx._open_connection()
curseur = cnx.cursor()
curseur.callproc("getperson", [1])
personnes = curseur.fetchall()
pour personne chez les personnes :
imprimer (personne)
cnx.close()</pre>
<p>...renvoie "mysql.connector.errors.InterfaceError : Il n'y a aucun jeu de résultats à obtenir." Il y a un comportement étrange supplémentaire en utilisant la méthode curseur.execute(), comme celui-ci... </ p>
<pre class="brush:php;toolbar:false;">importer mysql.connector
cnx = mysql.connector.connect(user='root', host='127.0.0.1', database='mytestdb')
cnx._open_connection()
curseur = cnx.cursor()
curseur.execute("appeler getperson(1)")
personnes = curseur.fetchall()
pour personne chez les personnes :
imprimer (personne)
cnx.close()</pre>
<p> ... car il produit "mysql.connector.errors.InterfaceError : utilisation de cmd_query_iter pour les instructions avec plusieurs requêtes" suivi de "mysql.connector.errors.InterfaceError : utilisation de multi=True lors de l'exécution de plusieurs instructions", malgré le fait que je ne renvoie qu’un seul résultat de requête plutôt que plusieurs jeux de résultats. Le connecteur MySQL Python traite-t-il les appels d'exécution aux procédures stockées comme des requêtes doubles ? Comment appeler une procédure stockée et obtenir les résultats ? Je ne veux vraiment pas utiliser du SQL dynamique dans mon code. Merci d'avance pour tout conseil! </p>
Obtenir le résultat d'une procédure stockée après un appel
cursor.callproc
dépend des facteurs suivants :DBAPI Spécification dans
上有这样的说法光标.callproc
:En fait, l'utilisation de la valeur de retour de Cursor.callproc ne fonctionne que si la procédure renvoie une seule ligne et que le nombre de colonnes correspond au nombre de paramètres INOUT et OUT, il y a donc quelques changements dans la façon dont les résultats sont gérés.
Voici comment les principaux packages de connecteurs MySQL Python gèrent ces situations : MySQL Connector, mysqlclient (MySQLdb) et PyMySQL.
Résultat sur une seule ligne, renvoyé via les paramètres INOUT ou OUT
MySQL Connector renvoie une copie modifiée de la séquence d'entrée comme valeur de retour de
cursor.callproc
; la valeur est un tuple.mysqlclient et PyMySQL nécessitent d'interroger la base de données pour les paramètres de sortie, puis d'obtenir les résultats via un curseur ; la valeur est un tuple de tuples. Le nom du paramètre à interroger est sous la forme
'@_{procedure_name}_{params.index(param)}'
Une ou plusieurs lignes dans un seul ensemble de résultats, aucun paramètre INOUT ou OUT n'est défini
Connecteur MySQL via la méthode stored_results du curseur (
cursor.stored_results
ne fait pas partie de la spécification DBAPI)mysqlclient et PyMySQL exposent les résultats via les méthodes fetch* du curseur
Plusieurs jeux de résultats, aucun paramètre INOUT ou OUT défini
MySQL Connector expose les résultats via la
stored_results
méthode du curseurmysqlclient et PyMySQL nécessitent l'appel de cursor.nextset pour passer à l'ensemble de résultats suivant. Notez qu'un ensemble de résultats vide supplémentaire peut être renvoyé, qui est le résultat de l'appel de la procédure (si
cursor.nextset
检索结果集而不是仅调用 cursor.fetchall est passé une fois).Informations sur la version
Avez-vous essayé de sélectionner l'un des ensembles de résultats ?
Même si vous n'avez qu'un seul
SELECT
stmt, il peut allouer plusieurs ensembles de résultats. Je sais que cela est fait dans les procédures stockées MySQLi de PHP pour permettre le retour des variables INOUT et OUT (encore une fois, ce n'est pas le cas, mais peut-être qu'elles sont allouées de toute façon).Le code complet que j'utilise (en cours d'exécution) est :