LAST_INSERT_ID()始终返回0(RMySQL)-单独的连接问题 在一些案例中发现的原始示例
根据这一点,下面的SQL语句应该给我一个向量LAST_INSERT_ID()始终返回0(RMySQL)-单独的连接问题 在一些案例中发现的原始示例,mysql,r,rmysql,last-insert-id,Mysql,R,Rmysql,Last Insert Id,根据这一点,下面的SQL语句应该给我一个向量 1,2,2,2,2最后: require("RMySQL") con <- dbConnect( dbDriver("MySQL"), db="your_db", user="your_user", password="your_pw", host="localhost" ) > con <MySQLConnection:(6640,122)> > dbSendQuery(co
1,2,2,2,2
最后:
require("RMySQL")
con <- dbConnect(
dbDriver("MySQL"),
db="your_db",
user="your_user",
password="your_pw",
host="localhost"
)
> con
<MySQLConnection:(6640,122)>
> dbSendQuery(con, "DROP TABLE IF EXISTS t;")
<MySQLResult:(6640,122,0)>
> dbSendQuery(con, "CREATE TABLE t (i INT NOT NULL AUTO_INCREMENT PRIMARY KEY);")
<MySQLResult:(6640,122,1)>
> dbSendQuery(con, "INSERT INTO t VALUES(NULL);")
<MySQLResult:(6640,122,2)>
> dbGetQuery(con, "SELECT LAST_INSERT_ID() FROM t;")
LAST_INSERT_ID()
1 0
> dbSendQuery(con, "INSERT INTO t VALUES(NULL),(NULL),(NULL);")
<MySQLResult:(6640,122,3)>
> dbGetQuery(con, "SELECT LAST_INSERT_ID() FROM t;")
LAST_INSERT_ID()
1 0
2 0
3 0
4 0
嗯,事实并非如此;-)
我用谷歌搜索了一下,发现,LAST\u INSERT\u ID()
是“连接感知”的,即如果要正常工作,必须使用相同的连接。然而,我认为通过将连接对象分配给con
,我可以确保在上面的每一个语句中都使用了相同的连接
嗯,显然不是;-)有人能帮我解释一下和/或解决办法吗?
但是,使用类似于select max()from
的方法并不能解决这一问题,因为我正在运行多个线程,这些线程同时向数据库写入数据,如果这样做的话,就会搞乱ID检索
谢谢
截至2012年4月20日的调查结果
- 多亏了你,我才能够更深入地了解这个问题。似乎
函数并不真正关心显式的RMySQL
参数,而是在每次连接到数据库时在后台打开新的连接。可能也有一些很好的理由。然而,有人知道如何避免这种情况吗李>conn
- 刚刚联系了Jeffrey Horner(软件包的维护人员)。这似乎是Windows的问题。在Linux上为他工作:-/
>dbGetInfo(con)
$host
[1] “本地主机”
$user
[1] “您的用户”
$dbname
[1] “您的数据库”
$conType
[1] “通过TCP/IP的本地主机”
$serverVersion
[1] "5.5.20"
$protocolVersion
[1] 10
$threadId
[1] 673489
$rsId
$rsId[[1]]
>dbGetInfo(dbDriver(“MySQL”))
$drvName
[1] “MySQL”
$connectionId
$connectionId[[1]]
$connectionId[[2]]
$connectionId[[3]]
$fetch\u default\u rec
[1] 500
$managerId
$length
[1] 16
$num_con
[1] 3
美元柜台
[1] 179
$clientVersion
[1] "5.5.20"
>dbListConnections(dbDriver(“MySQL”))
[[1]]
[[2]]
[[3]]
您正在将NULL
值插入主键列。由于不能有两行具有相同的主键,因此可能没有实际插入任何真实数据(这也可能是您希望捕获的错误)。尝试:
执行该操作将为最后一个插入id提供两个不同的值
编辑:误解。有关LAST\u INSERT\u ID
的详细信息,请参阅。修改后的答案:如果未在自动增量
列中指定值,则应返回上次插入ID
值。在这种情况下,请尝试:
INSERT INTO t DEFAULT VALUES
我们发现了一个非常有趣的解决方案:
res <- dbSendQuery(con, "INSERT INTO t VALUES (5);")
res <- dbSendQuery(con, "SELECT LAST_INSERT_ID();")
fetch(res)
res我找到了一个有效的解决方案。stephan mc的回复中也提到了这一点,但作为第二种选择。第一个对我不起作用,所以我认为这可能值得强调更多
无论如何,诀窍是在INSERT
和SELECT LAST\u INSERT\u ID()之间运行dbClearResult()
:
>库(“RMySQL”)
>con dbSendQuery(con,“如果存在,则删除表t;”)
>dbSendQuery(con,“创建表t(i INT NOT NULL自动增量主键);”)
>如果不使用t
中的选择最后一个插入ID(),则无需指定“FROM”子句。函数LAST\u INSERT\u ID()
将为您提供MySQL生成的最后一个自动增量,因此不应指定表。尝试使用选择最后一个插入ID()代码>。另外,对于您的上一次查询-last\u INSERT\u ID
不会产生有意义的结果(特别是,您不会得到第三次插入的正确值)。@N.B:谢谢您的回答。简单地从文章中复制语句,但即使我从
部分中删除了:相同的图片:-/Scope out dbGetInfo()和dbListConnections()。他们应该告诉你一些更有用的信息。@Jeff:谢谢,但我不确定我是否完全理解这些信息到底告诉了我什么。“dbListConnections返回驱动程序drv上当前打开的所有连接的列表。实现单个连接的驱动程序将返回单个连接对象。”->有没有一种方法可以使用实现单连接的MySQL驱动程序?将NULL
插入AUTO_INCREMENT
列正是使其自动递增的原因。如果您提供一个显式的值,它将对LAST\u INSERT\u ID()
没有影响。我稍微修改了示例的第二部分,使其更“真实”,例如:一个ID/UID列(I
),在“实际数据”列(x
)上,并为x
列插入实际值。仍然不影响上次插入的ID()。这是虫子吗?奇怪。。。不知道那里发生了什么事@杰夫艾伦:谢谢你的回答;-)不确定您所说的插入t默认值是什么意思
。那是有效的陈述吗?因为我在运行“原始”表t时出错(即只有一列I
)。@Rappster:这是SQL Server
中的有效语句,但在MySQL
中无效。至于MySQL
部分,您的原始语句没有问题,问题(很可能)在于连接切换。您可以通过发出SELECT CONNECTION\u ID()
来检查它,并查看该值是否仍然存在。
dbSendQuery(con, "INSERT INTO t VALUES(5);")
INSERT INTO t DEFAULT VALUES
res <- dbSendQuery(con, "INSERT INTO t VALUES (5);")
res <- dbSendQuery(con, "SELECT LAST_INSERT_ID();")
fetch(res)
> library("RMySQL")
> con <- dbConnect(MySQL())
> dbSendQuery(con, "DROP TABLE IF EXISTS t;")
> dbSendQuery(con, "CREATE TABLE t (i INT NOT NULL AUTO_INCREMENT PRIMARY KEY);")
> res <- dbSendQuery(con, "INSERT INTO t VALUES (NULL);")
# doesn't work:
> dbGetQuery(con, "SELECT LAST_INSERT_ID();")
LAST_INSERT_ID()
1 0
# works:
> dbClearResult(rs)
> dbGetQuery(con, "SELECT LAST_INSERT_ID();")
LAST_INSERT_ID()
1 1