我正在构建一个用于内部使用的包,并试图从用户中抽象出所有可能的数据库交互.我需要连接到数据库并断开与函数内的数据库的连接(我认为).但是,断开连接不起作用.
`my_func = function(){
con = DBI::dbConnect(RSQLite::SQLite(), 'db_location.sqlite')
r = DBI::dbSendQuery("SELECT * ...")
dat = DBI::dbFetch(r)
DBI::dbDisconnect(con)
return(dat)
}`
Run Code Online (Sandbox Code Playgroud)
如果你调用这个函数:
MY_LIBRARY::my_func()
返回数据但连接未终止并显示警告.
`Warning message:
In connection_release(conn@ptr) :
There are 1 result in use. The connection will be released when
they are closed`
Run Code Online (Sandbox Code Playgroud)
SQL查询通常是一个三步过程(忽略连接管理):
第三步很重要,因为未清除它代表了为该查询保留的资源.某些数据库连接不允许多个同时未清除的结果,一次只允许一个查询.
这在历史上已经完成:
res <- dbSendQuery(con, "SELECT ...")
dat <- dbFetch(res)
dbClearResult(res)
Run Code Online (Sandbox Code Playgroud)
前段时间(不知道版本),DBI提供了一个强大的便利功能,可以将所有这三行改为一行代码:
dat <- dbGetQuery(con, "SELECT ...")
Run Code Online (Sandbox Code Playgroud)
当查询未返回数据时,此函数不适用,例如,UPDATE或者INSERT,在这种情况下,您应该使用dbSendStatement(可选地后跟dbGetRowsAffected)或dbExecute(自动调用dbGetRowsAffected).
你应该不使用dbGetQuery发送数据,返回查询的时候,当您使用SQL参数(以缓解SQL注入).相反,你将返回使用dbSendQuery,dbBind(对于参数)dbFetch,和dbClearResult.