2017-09-17 2 views
1

a bug in dbplyr으로 인해 copy_tocompute은 현재 SQL Server 연결에서 작동하지 않습니다.dplyr 파이프 라인에서 SQL Server 테이블을 만드는 방법

connStr <- "driver=ODBC Driver 13 for SQL Server;server=localhost;..." 
db <- DBI::dbConnect(odbc::odbc(), .connection_string=connStr) 

copy_to(db, mtcars) 
#Error: <SQL> 'CREATE TEMPORARY TABLE "mtcars" (
# "row_names" varchar(255), 
# "mpg" FLOAT, 
# ... 
# nanodbc/nanodbc.cpp:1587: 42000: [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Unknown object type 'TEMPORARY' used in a CREATE, DROP, or ALTER statement. 

# use raw DBI functionality to create table 
DBI::dbWriteTable(db, "mtcars", mtcars) 

qry <- tbl(db, "mtcars") %>% group_by(am) %>% summarise(m=mean(mpg)) 

compute(qry) 
#Error: <SQL> 'CREATE TEMPORARY TABLE "isrxofsskr" AS SELECT "am" AS "am", "m" #AS "m" 
#FROM (SELECT "am", AVG("mpg") AS "m" 
#FROM "mtcars" 
#GROUP BY "am") "htrkkxabrn"' 
# nanodbc/nanodbc.cpp:1587: 42000: [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Unknown object type 'TEMPORARY' used in a CREATE, DROP, or ALTER statement. 

이 문제를 해결 dbplyr의 REPO에 활성 PR,하지만이 병합 될 때 (또는 CRAN에 도달 할 때) 전혀 표시가있다. 그 동안 R에서 데이터를 읽지 않고 쿼리에서 테이블을 만드는 방법은 무엇입니까?

+0

@ Hack-R이 맞습니다. 영구적으로 또는 임시 테이블을 만들지 여부를 선택하는 것이 이상적입니다. –

+0

이 질문은 바보 같은 질문 일 수 있습니다. 그러나 버그가 약간 잘못된 SQL 구문이므로 패키지 소스를 약간 수정하여 수정할 수는 없습니까? 난 그냥 "TEMPORARY"라는 단어를 제거 할 필요가 있다고 생각한다. (또는 끌어 오기 요청에서 코드를 사용한다. 아마도 포크를 병합 한 다음 포크를 설치하기 위해 install_github를 사용하면된다.). –

답변

1

dbplyr repo의 PR이 어쨌든 glitch되고 전체 테이블을 다시 쓰기 전에 메모리로 가져옵니다.

문제를 해결하려면 dbplyr 제네릭 용으로 몇 가지 MSSQL 관련 메서드를 만들어야합니다. 아래에 나열되어 있습니다. 또한 dbplyr repo에 게시했습니다. (제대로 작동한다고 가정하면) 너무 오래 전에 병합되어야합니다.

#' @export 
`db_compute.Microsoft SQL Server` <- function(con, table, sql, temporary=TRUE, 
    unique_indexes=list(), indexes=list(), ...) 
{ 
    # check that name has prefixed '##' if temporary 
    if(temporary && substr(table, 1, 1) != "#") 
     table <- paste0("##", table) 

    if(!is.list(indexes)) 
     indexes <- as.list(indexes) 

    if(!is.list(unique_indexes)) 
     unique_indexes <- as.list(unique_indexes) 

    db_save_query(con, sql, table, temporary=temporary) 
    db_create_indexes(con, table, unique_indexes, unique=TRUE) 
    db_create_indexes(con, table, indexes, unique=FALSE) 
    table 
} 


#' @export 
`db_save_query.Microsoft SQL Server` <- function(con, sql, name, temporary=TRUE, ...) 
{ 
    # check that name has prefixed '##' if temporary 
    if(temporary && substr(name, 1, 1) != "#") 
     name <- paste0("##", name) 

    tt_sql <- build_sql("SELECT * INTO ", ident_q(name), 
         " FROM (", sql, ") ", ident_q(name), con=con) 

    dbExecute(con, tt_sql) 
    name 
} 

참고 : 바비 테이블 대응 형일 수 없습니다. 테스트가 권장됩니다.

관련 문제