2017-06-19 84 views
0

我在SQL Server 2016中有一個存儲過程,其中我正在執行一個外部R腳本。我無法弄清楚爲什麼該程序適用於我,但是隻要有人運行它,他們就會得到這個錯誤。他們運行一次後,我還不能運行的程序,這個錯誤是默認的結果:在SSMS 2016中使用R腳本存儲過程錯誤

Location: tmpilb.cpp:2532 
Expression: fFalse 
SPID:  76 
Process ID: 2036 
Description:  Attempt to access expired blob handle (1) 
Msg 21, Level 20, State 1, Line 0 
Warning: Fatal error 3624 occurred at Jun 19 2017 3:07PM. Note the error   
and time, and contact your system administrator. 
Msg 596, Level 21, State 1, Line 0 
Cannot continue the execution because the session is in the kill state. 
Msg 0, Level 20, State 0, Line 0 
A severe error occurred on the current command. The results, if any, should 
be discarded. 

的存儲過程執行[R腳本鏈接到通過RODBC一個單獨的數據庫,提取數據,進行操作,並將結果發送回SQL以填充表格。

編輯:包括存儲過程的代碼:

   USE [Park_Analytics] 
      GO 
      /****** Object: StoredProcedure [dbo].[storedproc] Script Date: 6/19/2017 2:40:38 PM ******/ 
      SET ANSI_NULLS ON 
      GO 
      SET QUOTED_IDENTIFIER ON 
      GO 
      ALTER procedure [dbo].[storedproc] 
        @startdate date NULL 

      AS 

       set @startdate = ISNULL(@startdate,DATEADD(wk,DATEDIFF(wk,7,GETDATE()),-15)) 

       declare @enddate datetime = dateadd(D,1,@startdate) 


      create table #temp_results 
         (Park NVARCHAR(max) NOT NULL, 
         Turbine int NOT NULL, 
         avg_wtgp_kw float NULL, 
         avg_metwndspd_ms float NULL, 
         avg_metextmp_degc float NULL, 
         st_wtgp_kw float NULL, 
         st_metwndspd_ms float NULL, 
         st_metextmp_degc float NULL, 
         site_avg_wtgp_kw float NULL, 
         site_avg_metwndspd_ms float NULL, 
         site_avg_metextmp_degc float NULL, 
         site_st_wtgp_kw float NULL, 
         site_st_metwndspd_ms float NULL, 
         site_st_metextmp_degc float NULL, 
         Z_Score_avg_wtgp_kw float NULL, 
         Z_Score_avg_metwndspd_ms float NULL, 
         Z_Score_avg_metextmp_degc float NULL, 
         Alarm_Level_Z_Score_avg_wtgp_kw float NULL, 
         Alarm_Level_Z_Score_avg_metwndspd_ms float NULL, 
         Alarm_Level_Z_Score_avg_metextmp_degc float NULL) 


      insert into #temp_results 
      EXEC sp_execute_external_script 
       @language = N'R' 
       ,@script = N' 
       library(RODBC) 

      # String to connect to global database 
      piglobal_str <- ''driver={SQL Server};server=Server.corp.org\\Servername;database=Assets;uid=generic_login;pwd=generic_pwd'' 

      # Connect to the database 
      Assets <- odbcDriverConnect(piglobal_str) 


            # Write SQL Query to execute within R 
          QueryString <- ''SELECT 
          w.wpp_name as wpp, 
          pd.wt, 
          pd.datetime, 
          pd.datetime_local, 
          avg_wtgp_kw, 
          avg_metwndspd_ms, 
          avg_metextmp_degc, 
          FROM [Assets].[dbo].[PI_Main10mindata] pd 
          left join [Assets].[dbo].PI_Main10mindata_temp pt on pt.wpp=pd.wpp and pt.datetime = pd.datetime and pt.wt=pd.wt 
          left join [Assets].[dbo].[pi_wpps] w on w.wpp_pi = pd.wpp 
          where pt.datetime between DATEADD(wk,DATEDIFF(wk,7,GETDATE()),-15) 
          and DATEADD(wk,DATEDIFF(wk,7,GETDATE()),-14) 
          order by pt.datetime'' 

        # Set query results to a dataframe. as.is parameter is to keep all datatypes exactly the same as they are read. 
         pidata <- sqlQuery(Assets, QueryString,as.is=TRUE) 

        # Closing the RODBC Channel 
        odbcClose(Assets) 
        # Basic data processing. Setting the datatype to numeric. 
         pidata[,-which(names(pidata) %in% c("datetime","datetime_local","wpp"))] <- 
         sapply(pidata[,-which(names(pidata) %in% c("datetime","datetime_local","wpp"))], function(x) as.numeric(x)) 

        # Filter on availability and on kW output 
         filtered <- pidata[pidata$avg_wtgst_int %in% c(100, 200) & pidata$avg_wtgp_kw > 500 & !(is.na(pidata$avg_wtgp_kw)),] 

        # Remove date columns and state int column. They wont be important from here on out until theyre put back into the SQL table. 
         df_turbinefilter <- filtered[,-which(names(filtered) %in% c("datetime","datetime_local","avg_wtgst_int"))] 

        # Taking out the "avg_" in front of all of the columns. Will make sense later when I rename columns after aggregations. 
         colnames(df_turbinefilter) <- gsub("avg_","",colnames(df_turbinefilter),perl = TRUE) 


          ## PERFORM AGGREGATIONS ## 
          library(reshape2) 
          df_melt <- melt(df_turbinefilter, id= c("wpp","wt")) 
          agged <- dcast(df_melt, wpp + wt ~ variable, mean) 
          df_meltst <- melt(df_turbinefilter, id=c("wpp","wt")) 
          aggedst <- dcast(df_meltst, wpp + wt ~ variable, sd) 


           # Aggregated data joining 
           # list of data.frames 
           list_of_df <- list(agged, aggedst) 

           # names of data.frames 
           names(list_of_df) <- c("avg", "st") 

           # my sequence and names of data.frames in a list 
           my_seq <- seq_along(list_of_df) 
           my_list_names <- names(list_of_df) 

           # Renaming new columns. Including avg_ and st_ for average and standard deviation. 
           for (i in my_seq) { 

            names(list_of_df[[my_seq[i]]]) <- 
            paste(my_list_names[i], names(list_of_df[[my_seq[i]]]), sep = "_") 

            } 

           # Binding the columns from the agged table (to keep the nomenclature) with the other aggregate calcs 
           scored_data <- cbind(agged[,which(names(agged) %in% c("wpp","wt"))], 
                list_of_df$avg[,-which(names(list_of_df$avg) %in% c("avg_wpp","avg_wt"))], 
                list_of_df$st[,-which(names(list_of_df$st) %in% c("st_wpp","st_wt"))] ) 

          ## SITE AGGREGATIONS ## 
          df_sitefilter <- df_turbinefilter[,-which(names(df_turbinefilter) %in% c("wt"))] 
          df_meltsite <- melt(df_sitefilter, id="wpp") 
          aggedsite <- dcast(df_meltsite, wpp ~ variable, mean) 
          df_meltstsite <- melt(df_sitefilter, id="wpp") 
          aggedstsite <- dcast(df_meltstsite, wpp ~ variable, sd) 
          # Bug - have to create a separate vector 
          wpp <- aggedsite$wpp 

          # Aggegrated data joining 
           # list of data.frames 
           list_of_dfs <- list(aggedsite, aggedstsite) 

           # names of data.frames 
           names(list_of_dfs) <- c("site_avg", "site_st") 

           # my sequence and names of data.frames in a list 
           my_seqs <- seq_along(list_of_dfs) 
           my_list_namess <- names(list_of_dfs) 

           # Renaming new columns. 
           for (i in my_seqs) { 

            names(list_of_dfs[[my_seqs[i]]]) <- 
             paste(my_list_namess[i], names(list_of_dfs[[my_seqs[i]]]), sep = "_") 

            } 

           # Binding the columns from the aggedsite table (after setting wpp as an object) to the other aggregate tables 
           scored_data_site <- cbind(wpp, 
            list_of_dfs$site_avg[,-which(names(list_of_dfs$site_avg) %in% c("site_avg_wpp"))], 
            list_of_dfs$site_st[,-which(names(list_of_dfs$site_st) %in% c("site_st_wpp"))]) 



         ## Main SIT Table: All turbine avgs, standard deviations, and site averages and standard deviations. 
         library(dplyr) 
         parent_df <- left_join(scored_data, scored_data_site, by = "wpp") 

         # Creating variables to keep the for-loop dynamic in the case that changes need to be made. 
          # Finding the number of columns associated with the tags. This will aid in calculating statistics. 
          tag_length <- length(df_turbinefilter[,-which(names(pidata) %in% c("wpp", "wt"))]) 
          # Finding the first index column number where the condition is met. This is how the for loop will start. 
          tag_start <- which.max(!(names(parent_df) %in% c("wpp","wt"))) 
          length_before_calcs <- length(parent_df) 


          ## PERFORMING STATISTICAL CALCULATIONS AND ADDING NEW COLUMNS: WTG Avg-Site Avg/(Site St.Dev ^2/WTG St. Dev) 
            for (i in tag_start:tag_length) { 

             parent_df[,ncol(parent_df) + 1] <- 
             (parent_df[,i]-parent_df[,i+2*tag_length])/((parent_df[,i+3*(tag_length)])^2/parent_df[,i+(tag_length)]) 

             names(parent_df)[ncol(parent_df)] <- paste0("Z_Score_",names(parent_df[i])) 

             } 


          ## ADDING AN ALARM LEVEL COLUMN (0, 1, 2) DEPENDING ON THE CURRENT Z_SCORE 

            for (i in (length_before_calcs+1):ncol(parent_df)) { 

             parent_df[,ncol(parent_df) + 1] <- 
             ifelse(abs(parent_df[,i])<1, 0,ifelse(1<=abs(parent_df[,i]), 1, ifelse(abs(parent_df[,i]) >=2,2,0))) 

             names(parent_df)[ncol(parent_df)] <- paste0("Alarm_Level_", names(parent_df[i])) 

            } 



       OutputDataSet <- parent_df' 


       ,@input_data_1 = N'' 

      insert into SIT_WTG(
      Date, 
      Park, 
      Turbine, 
      avg_wtgp_kw, 
      avg_metwndspd_ms, 
      avg_metextmp_degc, 
      st_wtgp_kw, 
      st_metwndspd_ms, 
      st_metextmp_degc, 
      site_avg_wtgp_kw, 
      site_avg_metwndspd_ms, 
      site_avg_metextmp_degc, 
      site_st_wtgp_kw, 
      site_st_metwndspd_ms, 
      site_st_metextmp_degc, 
      Z_Score_avg_wtgp_kw, 
      Z_Score_avg_metwndspd_ms, 
      Z_Score_avg_metextmp_degc, 
      Alarm_Level_Z_Score_avg_wtgp_kw, 
      Alarm_Level_Z_Score_avg_metwndspd_ms, 
      Alarm_Level_Z_Score_avg_metextmp_degc) 

      select @startdate as Date , * 

      from #temp_results t 





      drop table #temp_results 
+0

@Parfait,我已經添加了代碼。爲了確保數據安全,我做了一些更改。 –

+0

你在R代碼裏有''''的地方,你想'''' –

+0

@HongOoi這對於語法的清晰性有幫助,但並不能消除這個問題 –

回答

0

相當做了一些研究之後,我意識到,這個存儲過程沒有被自動重新編譯。我用

WITH RECOMPILE AS 

在存儲過程的開始,這解決了我的問題。