我正在构建一个供内部使用的软件包,并尝试从用户那里提取所有可能的数据库交互。我需要连接到数据库,并从函数内的数据库断开连接(我认为)。但是,断开连接不起作用。
`my_func = function(){
con = DBI::dbConnect(RSQLite::SQLite(), 'db_location.sqlite')
r = DBI::dbSendQuery("SELECT * ...")
dat = DBI::dbFetch(r)
DBI::dbDisconnect(con)
return(dat)
}`
如果调用该函数:
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`
答案 0 :(得分:6)
SQL查询通常是一个三步过程(忽略连接管理):
第三步很重要,因为未清除表示代表该查询的资源。某些数据库连接不允许同时出现多个未清除的结果,一次只能进行一个查询。
这在历史上是通过以下方式完成的:
res <- dbSendQuery(con, "SELECT ...")
dat <- dbFetch(res)
dbClearResult(res)
前段时间(不知道版本),DBI
提供了强大的便捷功能,可将所有这三行更改为一行代码:
dat <- dbGetQuery(con, "SELECT ...")
当查询不返回数据时,例如UPDATE
或INSERT
,此功能不适用,在这种情况下,您应该使用dbSendStatement
(可选地,后面跟{{1} })或dbGetRowsAffected
(会自动调用dbExecute
)。
在使用SQL参数化(以减轻sql injection)的情况下发送数据返回查询时,您应该不使用dbGetRowsAffected
。相反,您将返回使用dbGetQuery
,dbSendQuery
(用于参数),dbBind
和dbFetch
。