将R变量传递给具有多个条目的RODBC sql查询?

Posted

技术标签:

【中文标题】将R变量传递给具有多个条目的RODBC sql查询?【英文标题】:Pass R variable to RODBC's sqlQuery with multiple entries? 【发布时间】:2011-11-14 20:34:51 【问题描述】:

我正在学习 R,向 SAS 挥手告别,我还是新手,不知何故我很难找到我正在寻找的东西。

但是对于这个特定的案例,我读到: Pass R variable to RODBC's sqlQuery? 并让它为我自己工作,只要我只在目标表中插入一个变量。

这是我的代码:

library(RODBC)
channel <- odbcConnect("test")
b <- sqlQuery(channel,
  "select top 1 Noinscr
   FROM table
   where PrixVente > 100
   order by datevente desc")

sqlQuery(channel,
   paste("insert into TestTable (UniqueID) Values (",b,")", sep = "")

当我将 top 1 替换为任何其他数字(假设为 top 2)并运行完全相同的代码时,我收到以下错误:

[1] "42000 195 [Microsoft][SQL Server Native Client 10.0][SQL Server]
    'c' is not a recognized built-in function name."      
[2] "[RODBC] ERROR: Could not SQLExecDirect 
    'insert into TestTable  (UniqueID) Values (c(8535735, 8449336))'"

我知道这是因为生成了一个额外的 c,我在给出命令时假设为列:paste(b)

那么在使用paste(b) 时,我怎样才能得到"8535735, 8449336" 而不是"c(8535735, 8449336)"?还是有其他方法可以做到这一点?

【问题讨论】:

【参考方案1】:

查看paste() 文档中的collapse 参数。尝试将b替换为paste(b, collapse = ", "),如下所示。

编辑 正如 Joshua 指出的那样,sqlQuery 返回一个 data.frame,而不是一个向量。因此,您可以使用paste(b[[1]], collapse = ", "),而不是paste(b, collapse = ", ")

library(RODBC)
channel <- odbcConnect("test")
b <- sqlQuery(channel,
  "select top 1 Noinscr
   FROM table
   where PrixVente > 100
   order by datevente desc")

sqlQuery(channel,
   ## note paste(b[[1]], collapse = ", ") in line below
   paste("insert into TestTable (UniqueID) Values (", paste(b[[1]], collapse = ", "),")", sep = "")

【讨论】:

仅供参考,这里是一个更复杂的版本,因为我不知道折叠参数(并且回答太晚了):Reduce(function(u, v) paste(u, ", ", v, sep=""), b) 添加了 [[1]],它就像一个魅力! c( ) 不见了!【参考方案2】:

假设b 看起来像这样:

b <- data.frame(Noinscr=c("8535735", "8449336"))

那么你只需要几个步骤:

# in case Noinscr is a factor
b$Noinscr <- as.character(b$Noinscr)
# convert the vector into a single string
# NOTE that I subset to get the vector, since b is a data.frame
B <- paste(b$Noinscr, collapse=",")
# create your query
paste("insert into TestTable (UniqueID) Values (",B,")", sep="")
# [1] "insert into TestTable (UniqueID) Values (8535735,8449336)"

你得到了奇怪的结果,因为sqlQuery 返回一个data.frame,而不是一个向量。正如您所了解的,在 data.frame(或任何列表)上使用 paste 会产生奇怪的结果,因为 paste 必须返回一个字符向量。

【讨论】:

我仍然遇到错误,这一次,我假设它是因为我将它转换为文本并尝试将文本放回一个浮点数的 sql 字段中。现在我收到以下错误:无法将类型“闭包”强制转换为“字符”类型的向量 @Felixthecat:我怀疑是这样,因为paste 会将b$Noinscr 转换为字符向量,即使它是数字或整数向量。该错误很可能意味着您正在尝试将函数转换为字符向量。仔细检查你的语法。 @Felixthecat:为了排除故障,您能否在您的问题中发布print(b) 的输出?

以上是关于将R变量传递给具有多个条目的RODBC sql查询?的主要内容,如果未能解决你的问题,请参考以下文章

使用 rodbc 包从 R 查询 sql server。需要将日期/时间值作为 where 语句的一部分传递到 sqlQuery

SQL查询丢失信息

R 编程:RODBC 和数据框

使用变量约束的 sqlQuery 不起作用。

以编程方式构建 SQL 查询 R/Shiny/RODBC

RODBC:执行包含多个语句的查询