在 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 中,是不是可以禁止“注意:全局变量没有可见绑定”?

如何将 R 会话中的值替换为 SQL 绑定变量占位符?

R CMD检查中的全局变量注释没有可见的绑定

R语言进行变量编码(recode):把dataframe中连续变量基于条件表达式转化为多个类别的离散变量(分类变量)使用attach函数绑定数据

setkey() 在 R CMD 检查时生成注释 - 全局变量没有可见绑定