根据这个post,下面的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(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
改编示例使其与实际用例相比原始用例更多:
dbSendQuery(con, "DROP TABLE IF EXISTS t;")
dbSendQuery(con, paste("CREATE TABLE t",
"(i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, x INT);"))
> dbGetQuery(con, "SELECT CONNECTION_ID();")
CONNECTION_ID()
1 673490
dbSendQuery(con, "INSERT INTO t SET x=1;")
> dbGetQuery(con, "SELECT CONNECTION_ID();")
CONNECTION_ID()
1 673491
> dbGetQuery(con, "SELECT LAST_INSERT_ID();")
LAST_INSERT_ID()
1 0
> dbGetQuery(con, "SELECT CONNECTION_ID();")
CONNECTION_ID()
1 673493
> 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
嗯,事实并非如此;-)
我已经google了一点,AFAIU,LAST_INSERT_ID()
是“连接感知”,因为如果要正常工作,必须使用相同的连接。但是,我认为通过将连接对象分配给con
,我确保在上面的每个语句中确实使用了相同的连接 。
嗯,显然不是;-)任何人都可以通过一些解释和/或解决方法帮助我吗?
但是,使用像select max(<ID>) from <TABLE>
这样的东西并不会削减它,因为我正在运行多个同时写入数据库的线程,因此如果这样做就会搞乱ID检索。
谢谢!
RMySQL
函数并不真正关心显式conn
参数,但每次连接到数据库时都会在后台打开新连接。这也可能是一些很好的理由。然而,有谁知道如何避免这种情况? 根据Jeff
的建议> dbGetInfo(con)
$host
[1] "localhost"
$user
[1] "your_user"
$dbname
[1] "your_db"
$conType
[1] "localhost via TCP/IP"
$serverVersion
[1] "5.5.20"
$protocolVersion
[1] 10
$threadId
[1] 673489
$rsId
$rsId[[1]]
<MySQLResult:(6640,171,3)>
> dbGetInfo(dbDriver("MySQL"))
$drvName
[1] "MySQL"
$connectionIds
$connectionIds[[1]]
<MySQLConnection:(6640,149)>
$connectionIds[[2]]
<MySQLConnection:(6640,112)>
$connectionIds[[3]]
<MySQLConnection:(6640,171)>
$fetch_default_rec
[1] 500
$managerId
<MySQLDriver:(6640)>
$length
[1] 16
$num_con
[1] 3
$counter
[1] 179
$clientVersion
[1] "5.5.20"
> dbListConnections(dbDriver("MySQL"))
[[1]]
<MySQLConnection:(6640,149)>
[[2]]
<MySQLConnection:(6640,112)>
[[3]]
<MySQLConnection:(6640,171)>
答案 0 :(得分:2)
我找到了一个有效的解决方案here。在stephan mc的回复中也提到过,但作为第二种选择。第一个不适合我,所以我认为这可能值得更多突出。
无论如何,诀窍是在dbClearResult()
和INSERT
之间运行SELECT LAST_INSERT_ID()
:
> 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
答案 1 :(得分:0)
您正在将NULL
值插入主键列。由于您不能拥有两个具有相同PK的行,因此您可能实际上并未插入任何实际数据(这也可能是您想要捕获的错误)。尝试:
dbSendQuery(con, "INSERT INTO t VALUES(5);")
执行它应该为last_insert_id提供两个不同的值。
编辑:被误解了。有关LAST_INSERT_ID
的详细信息,请参阅here。修改后的答案:如果您未在AUTO_INCREMENT
列中指定值,则,则应返回LAST_INSERT_ID
值。在这种情况下,请尝试:
INSERT INTO t DEFAULT VALUES
答案 2 :(得分:0)
我们找到了一个非常有趣的解决方案:
res <- dbSendQuery(con, "INSERT INTO t VALUES (5);")
res <- dbSendQuery(con, "SELECT LAST_INSERT_ID();")
fetch(res)
如果不起作用,请在发送最后一个ID请求之前使用dbClearResult(res)
。对我们来说,它已经成功了。