이렇게 쓰는 방법입니다. sqldf는 nse을 사용하는 대신 자연스럽게 문자열을 처리합니다. 따라서 소스를 사용하려는 data.frame의 문자열/이름을 전달하십시오.
library(sqldf); requireNamespace("checkmate")
db1 <- data.frame(a = c(1,2,3), d = c("a","b","c"), stringsAsFactors = F)
extract <- function(table_name, criteria_d) {
checkmate::assert_character(table_name, min.chars=1, len=1, any.missing=F)
checkmate::assert_character(criteria_d, min.chars=1, len=1, any.missing=F)
# Half-way attempt to prevent sql-injection. Values would need to be only numbers, letters, and underscores.
checkmate::assert_character(table_name, pattern="^\\w+$", len=1, any.missing=F)
checkmate::assert_character(criteria_d, pattern="^\\w+$", len=1, any.missing=F)
sql <- paste0("select * from [", table_name , "] where d ='", criteria_d, "'")
cat("Executing: `", sql, "`\n", sep="")
sqldf(sql, verbose=F)
}
extract("db1", "b")
어떤 이유로 변수의 문자열/이름을 알 수 없으면 extract(quote(db1), "b")
과 같습니다.
몇 노트.
- 변수의 이름을 'd'로 변경하여 더 명확하게했습니다.
- 나는
db2
과 db
이 시나리오와 관련이 없다고 생각했습니다.
- 코드를 너무 많이 변경하지 않으려 고 시도했습니다. 이 함수가 실제 데이터베이스에 연결된 경우 sql injection으로부터 보호하십시오.
- SQL이 조금 복잡해지면
glue::glue_sql()
을 사용해보십시오. 님의 질문에
편집 @ Sayak의 의견 :
data.frame 이름
c("db1", "db2") %>%
purrr::map_df(extract, "b")
의 벡터를 통해 루프를 사용 purrr::map_df()
과에 결과를 결합 단일 데이터 프레임 :
Executing: `select * from [db1] where d ='b'`
Executing: `select * from [db2] where d ='b'`
a d
1 2 b
2 1 b
다음 전화 번호가 dplyr::bind_rows()
이 아니어도 꽤 매끄 럽습니다.
당신은 (항상 "B"아니, 그래서 즉) 그 열 당신의 extract()
함수의 매개 변수와 일치 (A data.frame으로 입력 포장과 purrr::pmap_df()
를 사용하여 기준을 변경해야하는 경우 :
을 우리는이에 마지막 라인을 변경하는 경우
library(sqldf)
extract <- function(x, envir = parent.frame(), verbose = TRUE, ...) {
fn$sqldf("select * from [$x] where b = 'b'", envir = envir, verbose = verbose, ...)
}
# sample runs
extract("db1")
extract("db2")
Map(extract, c("db1", "db2"))
db <- setNames(db, c("db1", "db2"))
lapply(names(db), extract, envir = list2env(db))
후 출력 구성 요소 이름을하지만, 그렇지 않으면 동일합니다 :
ds_input <- tibble::tribble(
~table_name, ~criteria_d,
"db1", "b",
"db1", "c",
"db2", "c"
)
ds_input %>%
purrr::pmap_df(extract)
# Executing: `select * from [db1] where d ='b'`
# Executing: `select * from [db1] where d ='c'`
# Executing: `select * from [db2] where d ='c'`
# a d
# 1 2 b
# 2 3 c
# 3 3 c
SQL 표현식이 올바로 구성되지 않았습니다.이 행을 사용하면 다음과 같이 처리 할 수 있습니다. 'Example = paste0 ("select * from",'x ', "b ='", "b", " '", collapse = "")'. 함수의 내부 부분을 테스트하여 예상 출력을 생성하는지 확인하십시오. – lmo