我正在使用Python 2.7的mysql.connector模块。我已将代码分解为最简单的脚本,但我仍然遇到此问题。问题是,当我尝试获取最后一行id(在MySQL中为LAST_INSERT_ID
)时,无论插入多少行,都返回0。有没有人有这个问题的解决方案?
我的代码如下:
import mysql.connector
default_config = {
'user': 'root',
'password': 'password',
'host': '127.0.0.1',
'database': 'test',
'raise_on_warnings': True,
'autocommit': True
}
connection = mysql.connector.connect(**default_config)
cursor = connection.cursor()
args = ('name', 'desc')
cursor.callproc('sp_tools_insert', args)
lastid = cursor.lastrowid
print lastid # This returns 0 every time, regardless of number of inserts
我的存储过程如下所示:
CREATE PROCEDURE `sp_tools_insert`
(
IN p_name VARCHAR(45),
IN p_description VARCHAR(255)
)
BEGIN
INSERT INTO TOOLS
(
tool_name,
description
)
VALUES
(
p_name,
p_description
);
END
这就是我的TOOLS
表的定义方式:
DROP TABLE IF EXISTS `test`.`TOOLS` ;
CREATE TABLE IF NOT EXISTS `test`.`TOOLS` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`tool_name` VARCHAR(45) NOT NULL,
`description` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
我已验证存储过程是否正常工作,.callproc()
调用按预期工作。唯一不起作用的是.lastrowid
电话。有什么建议吗?
答案 0 :(得分:7)
lastrowid
属性:
...返回先前INSERT或UPDATE语句为AUTO_INCREMENT列生成的值...
您还没有运行INSERT
或UPDATE
声明,而是运行CALL
声明。
要获取详细信息,您必须按照lastrowid
调用的mysql_insert_id
函数的C API文档链接。特别是:
对于生成mysql_insert_id()
值的存储过程,{p>CALL
在AUTO_INCREMENT
语句后返回0,因为在这种情况下mysql_insert_id()
适用于CALL
而不是LAST_INSERT_ID()
程序中的陈述。在该过程中,您可以在SQL级别使用AUTO_INCREMENT
来获取TOOLS
值。
我在此假设您的AUTO_INCREMENT
表确实有lastrowid
列;否则,你首先没有价值。
另外,请注意,这只是与您的断言相反的方式之一,LAST_INSERT_ID()
和{{1}}不是同一回事。值得一读LAST_INSERT_ID
的文档。
答案 1 :(得分:1)
@abarnert说.lastrowid
无法正常工作的原因是我没有打电话给INSERT
或UPDATE
,而是CALL
。因此,解决此问题的唯一方法是更改我的存储过程,如下所示:
CREATE PROCEDURE `sp_tools_insert`
(
IN p_name VARCHAR(45),
IN p_description VARCHAR(255)
)
BEGIN
INSERT INTO TOOLS
(
tool_name,
description
)
VALUES
(
p_name,
p_description
)
SELECT LAST_INSERT_ID();
END
现在,当您调用该存储过程时,您应该期望它返回插入行的ID,方法与从调用{{1}的存储过程的任何调用返回变量的方式相同。声明。
在这个例子中:
SELECT
我仍然没有弄清楚为什么args = ('name', 'desc')
cursor.callproc('sp_tools_insert', args)
for result in cursor.stored_results():
print result.fetchall() # Or result.fetchone() for just the first result
甚至存在,因为它永远不会与.lastrowid
或.callproc()
语句一起使用。如果有人对这个问题有任何见解,请告诉我!