Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用Python游标从存储过程返回结果_Python_Mysql_Stored Procedures - Fatal编程技术网

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

无法使用Python游标从存储过程返回结果,python,mysql,stored-procedures,Python,Mysql,Stored Procedures,出于某种奇怪的原因,我无法从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,

出于某种奇怪的原因,我无法从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
现在,将PyCharm与Python3.3结合使用,调用此存储过程时,我似乎无法检索任何内容。此代码可获得所需的结果:

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()来表示

。。。返回“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.interfaceeerror:Use cmd_query_iter for statements with multiple query”,然后是“mysql.connector.errors.interfaceeerror:Use multi=True when executing multiple statements”,尽管我只返回一个查询结果而不是多个结果集。MySQL-Python连接器是否将存储过程的execute调用视为双重查询?如何调用存储过程并返回结果?我真的不想在我的代码中使用动态SQL。谢谢你的建议

为什么不这样试试呢

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

你试过选择一个结果集吗

for result in cursor.stored_results():
    people = result.fetchall()
这可能是因为它正在分配多个结果集,即使您只有一个
SELECT
stmt。我知道在PHP的MySQLi存储过程中,这样做是为了允许INOUT和OUT变量返回(同样,您没有这些返回,但它可能以任何方式进行分配)

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


调用cursor.callproc后获取存储过程的结果取决于以下因素:

  • 调用过程的结果是否分配给INOUT或OUT参数
  • 结果是由单行还是结果集组成
  • 用于进行调用的python包
DBAPI在
cursor.callproc
上这样说:

使用给定的名称调用存储数据库过程。参数序列必须为过程期望的每个参数包含一个条目。调用的结果作为输入序列的修改副本返回。输入参数保持不变,输出和输入/输出参数替换为可能的新值

该过程还可以提供一个结果集作为输出。然后必须通过标准的.fetch*()方法使其可用

实际上,只有当过程返回一行且列数与INOUT和OUT参数的数目匹配时,使用cursor.callproc的返回值才能起作用,因此处理结果的方式会有所不同


下面是主要的MySQL-Python连接器包和如何处理这些情况

通过INOUT或OUT参数返回的单行结果

  • MySQL连接器返回输入序列的修改副本作为
    cursor.callproc
    的返回值;该值是一个元组

    params = [in_param, out_param1, out_param2]
    in_, out1, out2 = cursor.callproc("test_proc", params) 
    
  • mysqlclientPyMySQL要求查询数据库中的输出参数,然后通过光标获取结果;该值是元组的元组。要查询的参数名称的格式为
    '@{procedure\u name}{params.index(param)}'

单个结果集中的一行或多行,未定义INOUT或OUT参数

  • MySQL连接器通过游标的方法公开结果(
    cursor.stored_results
    不属于DBAPI规范)

  • mysqlclientPyMySQL通过游标的fetch*方法公开结果

    cursor.callproc("test_proc", params)
    results = cursor.fetchall()
    
多个结果集,未定义输入输出或输出参数

  • MySQL连接器通过游标的
    存储的\u结果
    方法公开结果

    cursor.callproc("test_proc", params)
    results = [r.fetchall() for r in cursor.stored_results()]
    
  • mysqlclientPyMySQL要求通过游标获取每个结果集,同时调用以前进到下一个结果集。请注意,可能会返回一个额外的空结果集,这是调用过程的结果(如果通过
    cursor.nextset
    检索结果集,而不是只调用
    cursor.fetchall
    一次,则在前面的示例中也会发生这种情况)


版本信息

$ mysql --version
mysql  Ver 15.1 Distrib 10.1.41-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

$ pip list | grep -i mysql
mysql-connector-python 8.0.18 
mysqlclient            1.4.6  
PyMySQL                0.9.3  

这不是比MySQL更符合SQL server语法吗?因为这在MySQL的PL/SQL中不是有效的命令。对于SQLServer的T-SQL,这是一个有效的命令,但这不是我在这个项目中使用的命令。MySQL调用存储过程的语法是
callproc\u name([arguments])
。非常好
results=[r.fetchall()代表游标中的r.stored_results()]
正是我所需要的。
cursor.callproc("test_proc", params)
results = [r.fetchall() for r in cursor.stored_results()]
cursor.callproc("test_proc", params)
results = cursor.fetchall()
cursor.callproc("test_proc", params)
results = [r.fetchall() for r in cursor.stored_results()]
cursor.callproc("test_proc", params)
results = [cursor.fetchall()]
while cursor.nextset():
    results.append(cursor.fetchall())
$ mysql --version
mysql  Ver 15.1 Distrib 10.1.41-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

$ pip list | grep -i mysql
mysql-connector-python 8.0.18 
mysqlclient            1.4.6  
PyMySQL                0.9.3