Friday, April 20, 2012

RMySQL: LAST_INSERT_ID() always returns 0 - separate connection issue or bug?

Original example as found in some post



According to this post the following SQL statements should give me a vector
1, 2, 2, 2, 2 in the end:



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


Following suggestions by N.B. and Jeff Allen



dbSendQuery(con, "DROP TABLE IF EXISTS t;")
dbSendQuery(con, paste("CREATE TABLE t",
"(i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, x INT);"))
dbSendQuery(con, "INSERT INTO t SET x=1;")
> dbGetQuery(con, "SELECT * FROM t;")
i x
1 1 1
> dbGetQuery(con, "SELECT LAST_INSERT_ID();")
LAST_INSERT_ID()
1 0
dbSendQuery(con, "INSERT INTO t SET x=2;")
> dbGetQuery(con, "SELECT LAST_INSERT_ID();")
LAST_INSERT_ID()
1 0
> dbGetQuery(con, "SELECT * FROM t;")
i x
1 1 1
2 2 2


Well, it doesn't, really ;-)



I've googled a bit and AFAIU, LAST_INSERT_ID() is "connection-aware" in the sense that the same connection must be used if it is to work properly. However, I thought that by assigning the connection object to con I was making sure that indeed the same connection is used in each of the statements above.



Well, apparently not ;-) Can anyone help me out with some explanations and/or workarounds?
Using something like select max(<ID>) from <TABLE> isn't going to cut it, though, as I'm running multiple threads that simultaneously write to the DB, thus messing up ID retrieval if done that way.



Thanks!





No comments:

Post a Comment