Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R使用dbBind将参数传递给SQL IN子句(可能没有胶水包?)_R_Rstudio_R Dbi - Fatal编程技术网

R使用dbBind将参数传递给SQL IN子句(可能没有胶水包?)

R使用dbBind将参数传递给SQL IN子句(可能没有胶水包?),r,rstudio,r-dbi,R,Rstudio,R Dbi,只是想知道是否可以使用DBI将参数传递给SQL查询IN子句?已尝试以下操作(以及许多变体,包括未命名的参数) con列表中的两个元素必须具有相同的长度。从?dbBind中的值部分: 绑定太多或太少的值,或参数名称错误或长度不等,也会引发错误。如果查询中的占位符已命名,则所有参数值必须具有名称(不能为空或NA),反之亦然,否则将引发错误 在《规范》dbBind中进一步说明: 此列表中的所有元素必须具有相同的长度,并且包含后端支持的值 以下内容适合我: library(RSQLite) con &l

只是想知道是否可以使用DBI将参数传递给SQL查询IN子句?已尝试以下操作(以及许多变体,包括未命名的参数)


con列表中的两个元素必须具有相同的长度。从
?dbBind
中的值部分:

绑定太多或太少的值,或参数名称错误或长度不等,也会引发错误。如果查询中的占位符已命名,则所有参数值必须具有名称(不能为空或NA),反之亦然,否则将引发错误

在《规范》dbBind中进一步说明:

此列表中的所有元素必须具有相同的长度,并且包含后端支持的值

以下内容适合我:

library(RSQLite)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbWriteTable(con, "iris", iris)
iris_result <- dbSendQuery(con, "SELECT * FROM iris WHERE [Petal.Length] = $PL and [Petal.Width] > $PW")
pl <- c(6.0, 5.1)
dbBind(iris_result, list(PL=pl, PW=rep(2.3, length(pl))))
dbFetch(iris_result)
库(RSQLite)

con如果您想使用
dbBind()
在SQL的
子句中
绑定一个未定义数量的实际值:您不能

library(RSQLite)

con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbWriteTable(con, "iris", iris)

iris_result <- dbSendQuery(con, "SELECT * FROM iris WHERE [Petal.Width] > $PW and [Petal.Length] in ($PL)")
dbBind(iris_result, list(PW=2.3, PL=list(6.0, 5.1)))
# Error in rsqlite_bind_rows(res@ptr, params) : Parameter 2 does not have length 1.
选项2(如果
元素中的
数量发生变化):
您还可以计算实际参数的数量,并在
子句中的
中生成相同数量的查询参数,然后使用
dbSendQuery
准备SQL查询。这将防止SQL代码注入:

in.params <- c(PL1=6.0, PL2=5.1, PL3=5.6)
sql <- paste0("SELECT * FROM iris WHERE [Petal.Width] > $PW and [Petal.Length] in (",
              paste0("$", names(in.params), collapse = ", "),
              ")")
iris_result <- dbSendQuery(con, sql)
dbBind(iris_result, c(list(PW=2.3), in.params))
dbFetch(iris_result)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
# 1          6.3         3.3          6.0         2.5 virginica
# 2          5.8         2.8          5.1         2.4 virginica
# 3          6.3         3.4          5.6         2.4 virginica
# 4          6.7         3.1          5.6         2.4 virginica

gsubfn包中的
in.params
fn$
在任何命令之前对其参数执行替换。这不是sql特有的,尽管sqldf确实使用该工具<代码>库(gsubfn);PW我猜在使用参数化查询时,使用原生的
DBI
(它是
RSQLite
的基础)是不可能的,因为
in
子句中的参数通常不能在SQL中参数化,但需要字符串连接来构建SQL查询字符串(打开各种SQL代码注入!)由于最初的帖子可能不清楚,我想补充一点,我的帖子的目的是确定是否可以使用原生DBI,并且我没有语法错误。否则,我并不反对使用胶水包装。仍然要检查下面的答案/其他评论(目前不在R前面),但是,@R Yoda,这回答了我的问题。
library(RSQLite)

con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbWriteTable(con, "iris", iris)

iris_result <- dbSendQuery(con, "SELECT * FROM iris WHERE [Petal.Width] > $PW and [Petal.Length] in ($PL)")
dbBind(iris_result, list(PW=2.3, PL=list(6.0, 5.1)))
# Error in rsqlite_bind_rows(res@ptr, params) : Parameter 2 does not have length 1.
con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbWriteTable(con, "iris", iris)

# Works only if you know the number of IN-elements in adavance...
iris_result <- dbSendQuery(con, "SELECT * FROM iris WHERE [Petal.Width] > $PW and [Petal.Length] in ($PL1, $PL2)")
dbBind(iris_result, list(PW=2.3, PL1=6.0, PL2=5.1))
dbFetch(iris_result)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
# 1          6.3         3.3          6.0         2.5 virginica
# 2          5.8         2.8          5.1         2.4 virginica
in.params <- c(PL1=6.0, PL2=5.1, PL3=5.6)
sql <- paste0("SELECT * FROM iris WHERE [Petal.Width] > $PW and [Petal.Length] in (",
              paste0("$", names(in.params), collapse = ", "),
              ")")
iris_result <- dbSendQuery(con, sql)
dbBind(iris_result, c(list(PW=2.3), in.params))
dbFetch(iris_result)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
# 1          6.3         3.3          6.0         2.5 virginica
# 2          5.8         2.8          5.1         2.4 virginica
# 3          6.3         3.4          5.6         2.4 virginica
# 4          6.7         3.1          5.6         2.4 virginica