在 R DBI 中绑定变量
Posted
技术标签:
【中文标题】在 R DBI 中绑定变量【英文标题】:Bind variables in R DBI 【发布时间】:2010-02-02 17:05:15 【问题描述】:在 R 的 DBI
包中,我没有找到使用绑定变量的工具。我确实找到了一份文档(2002 年的原始小插图),其中提到了绑定变量,“也许 DBI 可以在未来的某个时候实现此功能”,但看起来到目前为止还没有完成。
R 中的人用什么来代替?只是将字符串直接连接到 SQL 中?这在安全性和性能方面存在一些明显的问题。
编辑:
以下是占位符如何工作的示例:
query <- "SELECT numlegs FROM animals WHERE color=?"
result <- dbGetQuery(caseinfo, query, bind="green")
这不是一个经过深思熟虑的接口,但想法是您可以使用 bind
的值,并且驱动程序处理转义的细节(如果底层 API 本身不处理绑定变量)调用者必须重新实现它[糟糕]。
【问题讨论】:
您能否提供一些示例代码,可以按照您希望的方式运行?您希望绑定变量具有什么行为? 你的意思是这样的吗? ***.com/questions/2182337/… 我闻到了一种新的 DBI 的味道,它具有更好的功能。我们都会成为快乐的 beta 测试者,Ken.... 如果有一个新的 DBI 正在开发中,那就太好了。是否有一个 DBI 的代码存储库,我可以在某个地方破解,而我得到一些圆形 tuits 的机会微乎其微? 不,我是在开玩笑。 DBI 回到大卫詹姆斯,他不再在他曾经做过的地方工作。我指导了一名 Google Summer of Code 学生使用 DBI 创建 Postgresql 绑定;该项目现在作为 RPostgreSQL 在 CRAN 上(并且可以与新的维护者一起做,以便在学生离开时进一步扩展)。一个新的 DBI 将是一个值得重写的,或“DBI 2.0”,但也是一项艰巨的任务。你准备好了吗?你似乎是那个痒痒的人所以...... 【参考方案1】:对于像我刚刚在谷歌搜索 rsqlite 和 dbgetpreparedquery 之后遇到这个问题的任何人,似乎在最新版本的 rsqlite 中,您可以使用绑定变量运行 SELECT 查询。我刚刚运行了以下内容:
query <- "SELECT probe_type,next_base,color_channel FROM probes WHERE probeid=?"
probe.types.df <- dbGetPreparedQuery(con,que,bind.data=data.frame(probeids=ids))
这相对较快(从 450,000 行表中选择 2,000 行)并且非常有用。
仅供参考。
【讨论】:
我不清楚 dbgetpreparedquery 和 dbsendpreparedquery 之间有什么区别 据我了解,GetQuery
函数将结果作为数据帧返回,而SendQuery
函数返回一个游标,您可以使用fetch
方法从该游标中批量请求结果。查看 RSQLITE::query cran.r-project.org/web/packages/RSQLite/RSQLite.pdf 的文档【参考方案2】:
以下是 RSQLite 当前支持的绑定的摘要 参数。你是对的,目前不支持 选择,但没有充分的理由,我想补充 支持一下。
如果您想破解,您可以获得所有 DBI 相关的包在这里:
use --user=readonly --password=readonly
https://hedgehog.fhcrc.org/compbio/r-dbi/trunk
https://hedgehog.fhcrc.org/compbio/r-dbi/trunk/DBI
https://hedgehog.fhcrc.org/compbio/r-dbi/trunk/SQLite/RSQLite
我喜欢收到补丁,尤其是如果它们包含测试和
文档。请统一差异。我实际上做了所有我的
使用 git 进行开发,因此最好的情况是创建 say 的 git 克隆
RSQLite 然后将差异发送给我git format-patch -n
git-svn..
总之,这里有一些例子:
library("RSQLite")
make_data <- function(n)
alpha <- c(letters, as.character(0:9))
make_key <- function(n)
paste(sample(alpha, n, replace = TRUE), collapse = "")
keys <- sapply(sample(1:5, replace=TRUE), function(x) make_key(x))
counts <- sample(seq_len(1e4), n, replace = TRUE)
data.frame(key = keys, count = counts, stringsAsFactors = FALSE)
key_counts <- make_data(100)
db <- dbConnect(SQLite(), dbname = ":memory:")
sql <- "
create table keys (key text, count integer)
"
dbGetQuery(db, sql)
bulk_insert <- function(sql, key_counts)
dbBeginTransaction(db)
dbGetPreparedQuery(db, sql, bind.data = key_counts)
dbCommit(db)
dbGetQuery(db, "select count(*) from keys")[[1]]
## for all styles, you can have up to 999 parameters
## anonymous
sql <- "insert into keys values (?, ?)"
bulk_insert(sql, key_counts)
## named w/ :, $, @
## names are matched against column names of bind.data
sql <- "insert into keys values (:key, :count)"
bulk_insert(sql, key_counts[ , 2:1])
sql <- "insert into keys values ($key, $count)"
bulk_insert(sql, key_counts)
sql <- "insert into keys values (@key, @count)"
bulk_insert(sql, key_counts)
## indexed (NOT CURRENTLY SUPPORTED)
## sql <- "insert into keys values (?1, ?2)"
## bulk_insert(sql)
【讨论】:
【参考方案3】:嘿嘿 - 我刚刚发现我在这种情况下使用的 RSQLite 确实支持绑定变量:
http://cran.r-project.org/web/packages/RSQLite/NEWS
请参阅有关dbSendPreparedQuery()
和dbGetPreparedQuery()
的条目。
所以从理论上讲,这会变得很糟糕:
df <- data.frame()
for (x in data$guid)
query <- paste("SELECT uuid, cites, score FROM mytab WHERE uuid='",
x, "'", sep="")
df <- rbind(df, dbGetQuery(con, query))
进入这个:
df <- dbGetPreparedQuery(
con, "SELECT uuid, cites, score FROM mytab WHERE uuid=:guid", data)
不幸的是,当我实际尝试时,它似乎只适用于INSERT
语句等,而不适用于SELECT
语句,因为我收到错误:RS-DBI driver: (cannot have bound parameters on a SELECT statement)
。
提供这种能力会很棒。
下一步是将其提升到 DBI 本身,以便所有 DB 都可以利用它,并提供一个默认实现,就像我们现在所做的那样将它粘贴到字符串中。
【讨论】:
以上是关于在 R DBI 中绑定变量的主要内容,如果未能解决你的问题,请参考以下文章
Perl DBI Sybase Asanywhere 绑定变量问题
R语言进行变量编码(recode):把dataframe中连续变量基于条件表达式转化为多个类别的离散变量(分类变量)使用attach函数绑定数据