一尘不染

无法使用Python游标从存储过程返回结果

mysql

由于某些奇怪的原因,我无法从Python测试应用程序中的callproc调用中获得结果。MqSQL 5.2.47中的存储过程如下所示:

CREATE PROCEDURE `mytestdb`.`getperson` (IN personid INT)
BEGIN
   select person.person_id,
          person.person_fname,
          person.person_mi,
          person.person_lname,
          person.persongender_id,
          person.personjob_id
     from person
    where person.person_id = personid;
END

现在,在Python 3.3中使用PyCharm时,在调用此存储过程时似乎什么也找不到。这段代码为我提供了预期的结果:

import mysql.connector

cnx = mysql.connector.connect(user='root', host='127.0.0.1', database='mytestdb')
cnx._open_connection()
cursor = cnx.cursor()

cursor.execute("select * from person where person.person_id = 1")
people = cursor.fetchall()

for person in people:
    print(person)

cnx.close()

但是这段代码带有cursor.fetchall()或cursor.fetchone()…

import mysql.connector

cnx = mysql.connector.connect(user='root', host='127.0.0.1', database='mytestdb')
cnx._open_connection()
cursor = cnx.cursor()

cursor.callproc("getperson", [1])
people = cursor.fetchall()

for person in people:
    print(person)

cnx.close()

…返回“ mysql.connector.errors.InterfaceError:无结果可取。”
使用cursor.execute()方法还有一个额外的奇怪行为,例如…

import mysql.connector

cnx = mysql.connector.connect(user='root', host='127.0.0.1', database='mytestdb')
cnx._open_connection()
cursor = cnx.cursor()

cursor.execute("call getperson(1)")
people = cursor.fetchall()

for person in people:
    print(person)

cnx.close()

…因为它会产生“
mysql.connector.errors.InterfaceError:对具有多个查询的语句使用cmd_query_iter”,随后产生“
mysql.connector.errors.InterfaceError:在执行多个语句时使用multi =
True”,尽管事实是仅返回一个查询结果,而不返回多个结果集。MySQL
Python连接器是否将对存储过程的execute调用视为双重查询?我如何才能调用存储过程并返回结果?我真的不希望在代码中使用动态SQL。谢谢您的任何建议!


阅读 404

收藏
2020-05-17

共1个答案

一尘不染

您是否尝试过选择其中一个结果集?

for result in cursor.stored_results():
    people = result.fetchall()

即使您只有一个SELECTstmt
,它也可能正在分配多个结果集。我知道在PHP的MySQLi存储过程中,这样做是为了允许INOUT和OUT变量返回(这又一次,您什么也没有,但是也许无论如何都在分配)。

我正在使用(正在运行)的完整代码是:

import mysql.connector

cnx = mysql.connector.connect(user='me',password='pw',host='localhost',database='mydb')
cnx._open_connection()
cursor = cnx.cursor()

cursor.callproc("getperson",[1])

for result in cursor.stored_results():
    people=result.fetchall()

for person in people:
    print person

cnx.close()
2020-05-17