如何使用R将data.frame传递到SQL“ IN”条件?

时间:2019-04-08 09:55:40

标签: sql r dbplyr

我正在从R中的CSV文件读取值列表,并尝试将这些值传递到SQL(dbGetQuery)的IN条件中。有人可以帮我这个忙吗?

library(rJava)
library(RJDBC)
library(dbplyr)
library(tibble)
library(DBI)
library(RODBC)
library(data.table)


jdbcDriver <- JDBC("oracle.jdbc.OracleDriver",classPath="C://Users/********/Oracle_JDBC/ojdbc6.jar")

jdbcConnection <- dbConnect(jdbcDriver, "jdbc:oracle:thin:Rahul@//Host/DB", "User_name", "Password") 

## Setting working directory for the data
setwd("C:\\Users\\**********\\Desktop")

## reading csv file into data frame
pii<-read.csv("sample.csv")

pii

 PII_ID
S0094-5765(17)31236-5
S0094-5765(17)31420-0
S0094-5765(17)31508-4
S0094-5765(17)31522-9
S0094-5765(17)30772-5
S0094-5765(17)30773-7

PII_ID1<-dbplyr::build_sql(pii$PII_ID)

PII_ID1

<SQL> ('S0094-5765(17)31236-5', 'S0094-5765(17)31420-0', 'S0094-5765(17)31508-4', 'S0094-5765(17)31522-9', 'S0094-5765(17)30772-5', 'S0094-5765(17)30773-7')


Data<-dbGetQuery(jdbcConnection, "SELECT ARTICLE_ID FROM JRBI_OWNER.JRBI_ARTICLE_DIM WHERE PII_ID in  ?",(PII_ID1))

预期:

ARTICLE_ID
12345
23456
12356
14567
13456

实际结果:

[1] ARTICLE_ID
<0 rows> (or 0-length row.names)

1 个答案:

答案 0 :(得分:0)

您在第二个参数中传递给dbGetQuery的SQL代码只是一个文本字符串,因此您可以使用paste或等效字符串来构造它。

您正在追求类似以下的内容:

in_clause <- paste0("('", paste0(pii$PII_ID, collapse = "', '"), "')")

sql_text <- paste0("SELECT ARTICLE_ID 
              FROM JRBI_OWNER.JRBI_ARTICLE_DIM
              WHERE PII_ID IN ", in_clause)

 data <- dbGetQuery(jdbcConnection, sql_text)

但是,第一个paste0的确切形式取决于PII_ID的格式(我假设它是文本)以及这种格式在sql中的表示方式(我假设单引号)。

在将sql_text传递给dbGetQuery之前,确保检查pii是有效的SQL。

重要提示:仅当pii包含少量值(我建议少于10个)时,此方法才适用。如果pii包含大量值,那么您的查询将非常大,并且运行速度将非常缓慢。如果[]中有许多值,那么更好的方法是按照@nicola的注释进行联接或半联接。