Как передать data.frame в условие SQL IN, используя R? - PullRequest
0 голосов
/ 08 апреля 2019

Я читаю список значений из файла CSV в R и пытаюсь передать значения в состояние IN SQL (dbGetQuery). Может ли кто-нибудь помочь мне с этим?

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 голосов
/ 24 апреля 2019

Код SQL, который вы передаете во втором аргументе dbGetQuery, представляет собой просто текстовую строку, следовательно, вы можете сконструировать это, используя 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 проверен действительный SQL перед передачей его на dbGetQuery.

ВАЖНО: Этот подход подходит, только если pii содержит небольшое количество значений (я рекомендуюменее 10).Если pii содержит большое количество значений, ваш запрос будет очень большим и будет выполняться очень медленно.Если у вас есть много значений в pii, то лучшим вариантом будет соединение или полусоединение согласно комментарию @ nicola.

...