R,使用 RJDBC 调用 SQL 服务器存储过程

R, Call a SQL Server stored procedure with RJDBC

我想从 R 中的函数调用存储过程。请参阅下面的代码。不幸的是,这段代码只生成一个没有值的数据框。我想用 RJDBC&DBI 解决这个问题,因为 RODBC 似乎有问题。

 RPT_09_Hourly_Connected_v3<- function(Year, Month="NULL",State = "NULL",Region="NULL", City="NULL", District="NULL", Subdistrict="NULL" ,Address='NULL'){
  drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver", "/opt/sqljdbc_3.0/sqljdbc4.jar") 
  conn <- DBI::dbConnect(drv, "jdbc:sqlserver://***;databaseName=***;user=***;password=***")
  sqlText <- paste("exec [dbo].[RPT_09_Hourly_Connected_v3]@Year=",Year, 
                                                   ",@Month=",Month,
                                                   ",@State=",State,"",
                                                   ",@Region=",Region,"",
                                                   ",@City=N'",City,"'",
                                                   ",@District=",District,"",
                                                   ",@Subdistrict=",Subdistrict,"",
                                                   ",@Address=N'",Address,"'",
                                                   sep="")
  data <- RJDBC::dbGetQuery(conn,sqlText)
}
a<- RPT_09_Hourly_Connected_v3(Year = 2016)

> str(a)
'data.frame':   0 obs. of  9 variables:
 $ Regio          : chr 
 $ Stad           : chr 
 $ Stadsdeel      : chr 
 $ Buurtcombinatie: chr 
 $ Adres          : chr 
 $ Jaar           : num 
 $ Maand          : num 
 $ hourNR         : num 
 $ HoursConnected : num

这在 RODBC 崩溃之前对我有用。 RODBCRJDBC有区别吗?

RPT_09_Hourly_Connected_v3<- function(Year, Month="NULL",State = "NULL",Region="NULL", City="NULL", District="NULL", Subdistrict="NULL" ,Address='NULL'){
  dbhandle <- odbcConnect("***;DATABASE=***;UID=***;PWD=***")
  data <- sqlQuery(dbhandle,paste("exec [ dbo].[RPT_09_Hourly_Connected_v3]@Year=",Year,
                                  ",@Month=",Month,
                                  ",@State=",State,"",
                                  ",@Region=",Region,"",
                                  ",@City=N'",City,"'",
                                  ",@District=",District,"",
                                  ",@Subdistrict=",Subdistrict,"",
                                  ",@Address=N'",Address,"'",
                                  sep=""))
  odbcCloseAll()
  data
}

如果我手动执行 SQL 服务器中的存储过程,它将如下所示:

EXEC    @return_value = [dbo].[RPT_09_Hourly_Connected_v3]
        @Year = 2016,
        @Month = NULL,
        @State = NULL,
        @Region = NULL,
        @City = N'Amsterdam',
        @District = NULL,
        @Subdistrict = NULL,
        @Address = NULL

你能解释一下哪里出了问题以及如何解决吗?

我过去在 RJDBC:

中成功使用过这个

d <- dbGetQuery(conn, paste0("exec my_STOREDPROC @Field1= '",Field1,"';"))

这可能只是语法问题。很难说 w/o 一个可重现的例子。 注意额外的一组引号

我发现 RODBCext 更容易使用,因为它使用参数绑定。它还使使用 NA 代替 "NULL" 变得更容易,并消除了对正确匹配引号字符的担忧。

library(RODBCext)
RPT_09_Hourly_Connected_v3<- function(Year, Month=NA, State = NA, Region=NA, City=NA, District=NA, Subdistrict=NA ,Address=NA){
  ch <- odbcDriverConnect([connection_string])

  sqlText <- paste("exec [dbo].[RPT_09_Hourly_Connected_v3]@Year=? ", 
                                                   ",@Month=? ",
                                                   ",@State=? ",
                                                   ",@Region=? ",
                                                   ",@City=? ",
                                                   ",@District=? ",
                                                   ",@Subdistrict=? ",
                                                   ",@Address=? ",
                                                   sep="")
  sqlExecute(channel = ch,
    query = sqlText,
    data = list(Year, Month, State, Region, City, District, Subdistrict, Address),
    fetch = TRUE,
    stringAsFactors = FALSE)
}

我找到了一个非常简单的解决方案,但愿我之前就知道了!也许我的答案可以帮助其他人。

FACT_CHARGESESSION<- function (username, password, country = "NULL",state = "NULL", region = "NULL",city = "NULL",
                           district  = "NULL",subdistrict = "NULL", provider= "NULL",startDateView = "NULL",endDateView = "NULL") {



InstallCandidates <-c("DBI","rJava","RJDBC","dplyr")
  toInstall<-InstallCandidates[!InstallCandidates %in% library()$results[,1]]
  if(length(toInstall) !=0){install.packages(toInstall,repos="http://cran.r-project.org")}
  lapply(InstallCandidates,library,character.only=TRUE)
  rm("InstallCandidates","toInstall")

  NAME <- "dbo.R_00_ValidTransactions_ID_PW_v4"
  options(java.parameters = "- Xmx1024m")
  drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver", "/opt/sqljdbc_3.0/sqljdbc4.jar")
  conn <- dbConnect(drv, "jdbc:sqlserver://***.**.***.***;databaseName=****;user=***;password=***")
  # Make a SQL text 
  sqlText <- paste(NAME, paste(username,password, country,state,region,city,district,subdistrict,provider,startDateView,endDateView,sep=",")) 
  data <- dbGetQuery(conn,sqlText)

  return(data)
}

sqlText 的输出:

"dbo.R_00_ValidTransactions_ID_PW_v4 M.Kooi , Whosebug , NULL , NULL , Amsterdam , NULL , NULL , NULL , NULL , NULL , NULL "

您现在无需使用 SP 执行 window,只需在新查询 window.

中使用参数执行 SP