简体   繁体   English

带有动态字符串的 R dbGetQuery

[英]R dbGetQuery with dynamic string

FromThis post and This post , I got a way to write an rsqlite dynamic command.这篇文章这篇文章,我得到了一种编写 rsqlite 动态命令的方法。 However, it doesn't work for me.但是,它对我不起作用。 My data looks like:我的数据看起来像:

Id <- c(34, 22, 86)
sqlcmd <- paste("select col1, col2 from DB where ItemId =", Id, sep="")
Df <- dbGetQuery(conn, sqlcmd)

My sqlcmd gives me a list of strings as我的sqlcmd给了我一个字符串列表

"select col1, col2 from DB where STOREID =34"
"select col1, col2 from DB where STOREID =22"
"select col1, col2 from DB where STOREID =86"

However, when I pass sqlcmd to dbGetQuery , it only returns data with ItemId = 34 , which is the first element in the Id list.但是,当我将sqlcmd传递给dbGetQuery ,它只返回ItemId = 34数据,这是Id列表中的第一个元素。

I'm wondering if anyone has any ideas on why does this happen?我想知道是否有人对为什么会发生这种情况有任何想法? Any help would be appreciated!任何帮助,将不胜感激!

I would normally do this like this:我通常会这样做:

Id1 <- c(34, 22, 86)

Id2 <- paste(Id1, collapse = ", ")
sqlcmd <- paste("select col1, col2 from DB where ItemId in (", Id2, ")", sep="")
Df <- dbGetQuery(conn, sqlcmd)

However if you want to return a list of data frames for each id and run the query three times you could do:但是,如果您想为每个 id 返回数据框列表并运行查询三次,您可以执行以下操作:

sqlcmd <- paste("select col1, col2 from DB where ItemId in (", Id1, ")", sep="")    
dataList <- lapply(sqlcmd, function(x) dbGetQuery(conn, x)) 

Since I believe R DBI drivers have not yet implemented multiple SQL statements support, dbGetQuery only returns first statement.由于我相信 R DBI 驱动程序还没有实现多 SQL 语句支持, dbGetQuery只返回第一条语句。

Hence, you need to iteratively run your sqlcmd for multiple SQL statements such as with lapply to return a list of dataframes, followed by an rbind call for single master dataframe:因此,您需要为多个 SQL 语句迭代运行sqlcmd ,例如使用lapply返回数据帧列表,然后是对单个主数据帧的rbind调用:

Id <- c(34, 22, 86)
sqlcmd <- paste("select col1, col2 from DB where ItemId =", Id, sep="")

# LIST OF DATAFRAMES
df_list <- lapply(sqlcmd , function(x) dbGetQuery(conn, x)) 

# FINAL DATAFRAME
final_df <- do.call(rbind, df_list)

Alternatively, use a UNION or UNION ALL for one SQL statement.或者,对一个 SQL 语句使用UNIONUNION ALL

Id <- c(34, 22, 86)
sqlcmd <- paste("select col1, col2 from DB where ItemId =", Id, sep="")

single_sql <- paste(sqlcmd, collapse = " UNION ")
final_df <- dbGetQuery(conn, single_sql)

Or still use OR :或者仍然使用OR

single_sql <- paste("select col1, col2 from DB where ItemId =", 
                    paste(Id, collapse=" OR ItemId = "))

final_df <- dbGetQuery(conn, single_sql)

This also works with parametrized queries:这也适用于参数化查询:

library(RSQLite)
conn <- dbConnect(SQLite())
dbWriteTable(conn, "DB", data.frame(col1 = 1, col2 = 2, ItemId = 3))

Id <- c(34, 22, 86)
sqlcmd <- "select col1, col2 from DB where ItemId = ?"
Df <- dbGetQuery(conn, sqlcmd, params = list(Id))

Created on 2018-06-11 by the reprex package (v0.2.0).reprex 包(v0.2.0) 于2018年 6 月 11 日创建。

Recent versions of DBI and RSQLite will return a data frame that contains the results from these queries concatenated.最新版本的DBIRSQLite将返回一个数据框,其中包含这些查询串联的结果。

Just noting that using variables in a SQL query is generally discouraged, as it can make you susceptible to an injection attack.请注意,通常不鼓励在 SQL 查询中使用变量,因为它会使您容易受到注入攻击。 https://db.rstudio.com/best-practices/run-queries-safely/ https://db.rstudio.com/best-practices/run-queries-safely/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM