2009-02-18 103 views
7

我在MySQL数据库中有一个存储过程,它只更新日期列并返回前一个日期。如果我从MySQL客户端调用这个存储过程,它可以正常工作,但是当我尝试使用MySQLdb从Python调用存储过程时,我似乎无法让它给我返回值。使用MySQLdb从Python获取MySQL存储过程的返回值

下面的代码到存储过程:

CREATE PROCEDURE test_stuff.get_lastpoll() 
BEGIN 
    DECLARE POLLTIME TIMESTAMP DEFAULT NULL; 
    START TRANSACTION; 

    SELECT poll_date_time 
     FROM test_stuff.poll_table 
     LIMIT 1 
     INTO POLLTIME 
    FOR UPDATE; 

    IF POLLTIME IS NULL THEN 
     INSERT INTO 
       test_stuff.poll_table 
       (poll_date_time) 
     VALUES 
       (UTC_TIMESTAMP()); 

     COMMIT; 
     SELECT NULL as POLL_DATE_TIME; 
    ELSE 
     UPDATE test_stuff.poll_table SET poll_date_time = UTC_TIMESTAMP(); 
     COMMIT; 
     SELECT DATE_FORMAT(POLLTIME, '%Y-%m-%d %H:%i:%s') as POLL_DATE_TIME; 
    END IF; 
END 

我使用尝试调用存储过程的代码与此类似:

#!/usr/bin/python 

import sys 
import MySQLdb 

try: 
    mysql = MySQLdb.connect(user=User,passwd=Passwd,db="test_stuff") 
    mysql_cursor = mysql.cursor() 

    results=mysql_cursor.callproc("get_lastpoll",()) 
    print results 

    mysql_cursor.close() 
    mysql.close() 

except MySQLdb.Error, e: 
    print "MySQL Error %d: %s" % (e.args[0], e.args[1]) 
    sys.exit(1) 

我知道你能做到IN和OUT参数,但是从我可以从MySQLdb文档中确定的内容来看,这对于MySQLdb来说是不可能的。有没有人有任何线索我怎么能得到存储过程的结果?

如果我从SQL工具运行它,这里的输出:

POLL_DATE_TIME  
------------------- 
2009-02-18 22:27:07 

如果我运行Python脚本,它返回一个空集,这样的:

() 

回答

11

我有什么做的是修改Python代码使用execute()而不是callproc(),然后使用fetchone()得到结果。我自己回答,因为mluebke的回答并不完全(尽管它有帮助!)。

mysql_cursor.execute("call get_lastpoll();") 
results=mysql_cursor.fetchone() 
print results[0] 

这给了我正确的输出:

2009-02-19 17:10:42 
+0

如何在这种情况下将参数传递给游标 – sandeep 2014-10-30 08:52:40

6

你还是必须获取结果。

results = cursor.fetchone() 

results = cursor.fetchall() 

等。

+0

这帮我找到了答案,谢谢! – m0j0 2009-02-19 17:06:16

8

callproc也能正常工作,你不需要使用execute

mysql_cursor.callproc("get_lastpoll",()) 
result = mysql_cursor.fetchone() 
0

从API文档的MySQLdb库。在你看到存储过程返回的结果集之前,你需要调用cursor_obj.nextset()。这是因为对存储过程的调用会创建一个结果集。随后存储过程返回的结果集。

More info

+0

作为链接的文档状态,额外的空结果集将*返回*存储过程生成的结果集之后。在取出之前调用`nextset()`*会丢弃错误的结果集。 – Air 2014-07-10 17:57:31