RODBC:执行包含多个语句的查询

时间:2016-08-03 22:55:13

标签: sql r rodbc

我有一个返回varbinary输出参数的存储过程。我想从R调用它并捕获返回变量。我试过了:

qq <- "declare @mm varbinary(max); exec spTrain_df_to_op @mm_outer = @mm output; select @mm as model;"
conStr <- "Driver={SQL Server};Server=.;Database=airline_new;Trusted_Connection=TRUE;"
dbhandle <- odbcDriverConnect(conStr, rows_at_time = 1)
result <- sqlQuery(dbhandle, qq)

此操作失败,结果显示为字符(0)。可能是RODBC不想执行本质上是一系列查询。我该如何解决这个问题?

谢谢!

这是存储过程:

ALTER PROCEDURE [dbo].[spTrain_df_to_op]
  @mm_outer varbinary(max) output
AS
  BEGIN TRY
    exec sp_execute_external_script
      @language = N'R',
      @script = N'
        func <- function() {
          in_df[,"DayOfWeek"] <- factor(in_df[,"DayOfWeek"], levels=as.character(1:7))
          # The model formula
          formula <- ArrDelay ~ CRSDepTime + DayOfWeek + CRSDepHour:DayOfWeek
          # Train the model
          rxSetComputeContext("local")
          mm <- rxLinMod(formula, data=in_df, transformFunc=NULL, transformVars=NULL)
          mm <<- serialize(mm, connection=NULL)
        }
        result = func()
      ',
      @input_data_1 = N'select top 10000 ArrDelay,CRSDepTime,DayOfWeek,CRSDepHour from cleanData',
      @input_data_1_name = N'in_df',
      @params = N'@mm varbinary(max) output',
      @mm = @mm_outer output
  END TRY
  BEGIN CATCH
    THROW;
  END CATCH;

对于踢球,我尝试了以下方法:

qq = "declare @mm varbinary(max); select 2 as hello; select 1 as model"
conStr <- "Driver={SQL Server};Server=.;Database=airline_new;Trusted_Connection=TRUE;"
dbhandle <- odbcDriverConnect(conStr, rows_at_time = 1)
result <- sqlQuery(dbhandle, qq)

这只返回第一个查询的结果:

  hello
1     2

我也尝试将查询设置为

qq = paste0("SET NOCOUNT ON; declare @mm varbinary(max); ",
           "exec spTrain_df_to_op @mm_outer = @mm output; ",
           "SET NOCOUNT OFF; select @mm as model;")

仍然产生了角色(0)。

从查询中创建存储过程不是一种选择。

1 个答案:

答案 0 :(得分:2)

无可否认,我没有像在您的用例中那样尝试使用PL / SQL,但认为它应该可行,如果不希望它对其他人有用,可以运行存储在单个脚本中的多个查询。

您应该能够通过首先将脚本拆分为单个查询来实现此目的。如果使用半冒号作为分隔符(无论如何设置了多少查询,以及如何构建第二次尝试),您可以将查询拆分为查询向量,并通过循环单独运行每个查询。如果某些查询具有您希望以后访问的结果,则可以返回它们并将其存储在列表中。

library(RODBC)

# an example SQL Script containing multiple queries, seperated by semi-colon
example_script <- 
"select sysdate from dual;
commit;
select sysdate from dual;"

# split the string into a character vector of queries to run
split_queries <- strsplit(example_script, ";",)[[1]]

#prepeare a list to store results
list_of_results <- list() 


ch <- odbcConnect("XX",uid="XX", pwd="XX")

# loop through and run the queries, storing results (if any) in the list
for (i in 1:length(split_queries)) {

  list_of_results[[i]] <- sqlQuery(ch,
                                   split_queries[i],
                                   errors = FALSE)

  Sys.sleep(2)

}

odbcClose(ch)

# show list of results, of course these elements could be anything from strings to data.frames
list_of_results

[[1]]
              SYSDATE
1 2018-03-28 17:15:26

[[2]]
[1] -2

[[3]]
              SYSDATE
1 2018-03-28 17:15:30
  • 我已经提交了#34;提交;&#34;用来说明一个没有的命令 结果只会在结果列表中返回一个负整数 位置。

  • 我在sqlQuery中包含errors = FALSE,因为这将允许类似命令 &#34; drop table&#34;当表格在第一个工作地点不存在时 不停止循环。

我的大型脚本有多个 drop table 创建表对查询。这种方法允许我将整个脚本整合到R中并一次运行。通常我只是在最终查询的结果之后,所以我不会在我去的时候将事物存储在列表中,而是只有一个输出变量,当循环运行直到最终的select语句时它被覆盖将结果转储到变量中。