sql - SSMS 2016 中带有 R 脚本的存储过程错误

标签 sql r t-sql stored-procedures microsoft-r

我在 SQL Server 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

最佳答案

经过大量研究后,我意识到这个存储过程不会自动重新编译。我用过

WITH RECOMPILE AS

在存储过程的开头,这解决了我的问题。

关于sql - SSMS 2016 中带有 R 脚本的存储过程错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44639496/

相关文章:

r - 如何使用 gridGraphics 转换分类 TreeMap

r - 将列表组合成 R 中的单个列表

r - 保存输入 Shiny 的状态

sql - 收到警告 : Null value is eliminated by an aggregate or other SET operation

sql - 操作数数据类型 varchar 对于减法运算符无效

php - 我如何使这个 MySQL 查询工作?

sql - 打乱多行的列值

t-sql - 从表中删除所有唯一键 - T-SQL

sql - 根据不同列值返回行数据

sql - 按记录分组,然后从每组中获取最后一个升序排序记录?